tx · Hhmftx4zsDJmHpo15zEgE87hGgBjwxceqTdhKSvRnrc

3N5Xd7QVQZWntaJwha9Kg42is626GUPjtUW:  -0.14000000 Waves

2022.06.06 15:45 [2084512] smart account 3N5Xd7QVQZWntaJwha9Kg42is626GUPjtUW > SELF 0.00000000 Waves

{ "type": 13, "id": "Hhmftx4zsDJmHpo15zEgE87hGgBjwxceqTdhKSvRnrc", "fee": 14000000, "feeAssetId": null, "timestamp": 1654519525914, "version": 2, "chainId": 84, "sender": "3N5Xd7QVQZWntaJwha9Kg42is626GUPjtUW", "senderPublicKey": "DfbjpZJBbZwnUKysUkxCbWTE1ZWuoUb6Y6BZdu5iAE8j", "proofs": [ "qzXBgMtx5jvpj4WP7UiT3i1PzcbXNzqKTdN1jYEzvXDFEr9ZVZjwo8JLuAKn8jHt7FW6k14aePnbnPCWjLmDfCo", "4P2s71MrCzYE28pYL4KYyyFbp9p273rX9mMKrvJiVXibdiA34FQuRuYTFsb3iHo3tcP8VR34w4zdiDjQRfWYqjAA" ], "script": "base64:AAIFAAAAAAAAEvgIAhIAEgASBAoCAQESABIECgIBARIAEgASABIFCgMEAQgSABoMCgFBEgckbWF0Y2gwGgsKAUISBnN0cmluZxoMCgFDEgdub3RoaW5nGhEKAUQSDGFkbWluUHViS2V5MRoRCgFFEgxhZG1pblB1YktleTIaEQoBRhIMYWRtaW5QdWJLZXkzGhYKAUcSEWFkbWluUHViS2V5SW52b2tlGhQKAUgSD21vbmV5Qm94QWRkcmVzcxoPCgFJEgpnb3ZBZGRyZXNzGhcKAUoSEnN0YWtpbmdVU0ROQWRkcmVzcxoJCgFLEgRVU0ROGhIKAUwSDXN0YWtpbmdBc3NldHMaCwoBTRIGYWN0aXZlGhAKAU4SC3N0ckFzc2V0SWRBGhAKAU8SC3N0ckFzc2V0SWRCGg0KAVASCGFzc2V0SWRBGg0KAVESCGFzc2V0SWRCGg8KAVISCmFzc2V0TmFtZUEaBwoBUxICaWQaCgoBVBIFd2F2ZXMaDwoBVRIKYXNzZXROYW1lQhoNCgFWEghiYWxhbmNlQRoNCgFXEghiYWxhbmNlQhoRCgFYEgxzaGFyZUFzc2V0SWQaFQoBWRIQc2hhcmVBc3NldFN1cHBseRoOCgFaEglpbnZhcmlhbnQaDAoBYRIHdmVyc2lvbhofCgJhQRIZYWNjb3VudEJhbGFuY2VXaXRoU3Rha2VkQhoWCgJhQhIQaGFzRW5vdWdoQmFsYW5jZRoOCgJhQxIIc2tld25lc3MaBwoCYUQSAXgaBwoCYUUSAXkaEwoCYUYSDWludmFyaWFudENhbGMaCAoCYUcSAnNrGhkKAmFIEhNjYWxjdWxhdGVTZW5kQW1vdW50GhsKAmFJEhVhbW91bnRUb1NlbmRFc3RpbWF0ZWQaGwoCYUoSFW1pblRva2VuUmVjZWl2ZUFtb3VudBoYCgJhSxISdG9rZW5SZWNlaXZlQW1vdW50Gg0KAmFMEgd0b2tlbklkGiMKAmFNEh13b3JzdEFsbG93ZWROZXdJbnZhcmlhbnRSYXRpbxokCgJhThIeZGVsdGFCZXR3ZWVuTWF4QW5kTWluU2VuZFZhbHVlGhMKAmFPEg1nZXRTdGVwQW1vdW50GgkKAmFQEgNhY2MaCgoCYVESBHN0ZXAaEgoCYVISDGFtb3VudFRvU2VuZBoTCgJhUxINc3RlcEludmFyaWFudBoVCgJhVBIPYW1vdW50VG9TZW5kTWluGhIKAmFVEgxpbnZFc3RpbWF0ZWQaBwoCYVYSAWEaCAoCYVcSAiRsGggKAmFYEgIkcxoLCgJhWRIFJGFjYzAaCwoCYVoSBSRmMF8xGgkKAmFhEgNmZWUaEwoCYWISDWZlZUdvdmVybmFuY2UaDwoCYWMSCWZlZVNjYWxlNhoMCgJhZBIGc2NhbGUzGgwKAmFlEgZzY2FsZTgaDQoCYWYSB3NjYWxlMTYaFAoCYWcSDnNsaXBwYWdlU2NhbGUzGg0KAmFoEgdkaWdpdHM4GhMKAmFpEg1kQXBwVGhyZXNob2xkGhkKAmFqEhNkQXBwVGhyZXNob2xkU2NhbGUyGhwKAmFrEhZleGNoYW5nZVJhdGlvTGltaXRDb2VmGhgKAmFsEhJleGNoYW5nZVJhdGlvTGltaXQaCwoCYW0SBWFscGhhGhEKAmFuEgthbHBoYURpZ2l0cxoKCgJhbxIEYmV0YRoUCgJhcBIOYWNjb3VudEJhbGFuY2UaDQoCYXESB2Fzc2V0SWQaEgoCYXISDHN0YWtlZEFtb3VudBocCgJhcxIWc3Rha2VkQW1vdW50Q2FsY3VsYXRlZBoJCgJhdBIDYUlkGgcKAmF1EgFpGhMKAmF2Eg1zdGFrZWRBbW91bnRBGhMKAmF3Eg1zdGFrZWRBbW91bnRCGhcKAmF4EhFhdmFpbGFibGVCYWxhbmNlQRoXCgJheRIRYXZhaWxhYmxlQmFsYW5jZUIaHwoCYXoSGWFjY291bnRCYWxhbmNlV2l0aFN0YWtlZEEaDQoBYhIIa1ZlcnNpb24aEQoCYkESCyR0MDk1MTQ5NTgwGhoKAmJCEhRjYWxjdWxhdGVGZWVEaXNjb3VudBoOCgJiQxIIdXNlckFkZHIaEAoCYkQSCnN3b3BBbW91bnQaFAoCYkUSDmRpc2NvdW50VmFsdWVzGg8KAmJGEglkaXNjb3VudHMaHAoCYkcSFmNhbGNCYWxhbmNlQW5kUG10UmF0aW8aDgoCYkgSCEFCYWxhbmNlGg4KAmJJEghCQmFsYW5jZRoYCgJiShISbWluQW1vdW50VG9SZWNlaXZlGg8KAmJLEglwbXRBbW91bnQaEAoCYkwSCnBtdEFzc2V0SWQaCwoCYk0SBXJhdGlvGgwKAmJOEgZwcmF0aW8aEwoCYk8SDSR0MDExNDk4MTE1NzUaEAoCYlASCnBtdEFtb3VudEEaEQoCYlESC3BtdEFzc2V0SWRBGhMKAmJSEg0kdDAxMTU4MDExNjU3GhAKAmJTEgpwbXRBbW91bnRCGhEKAmJUEgtwbXRBc3NldElkQhoTCgJiVRINJHQwMTE2NjIxMTczORoUCgJiVhIOcG10U3RyQXNzZXRJZEEaEwoCYlcSDXBtdEFzc2V0TmFtZUEaEgoCYlgSDHBtdERlY2ltYWxzQRoTCgJiWRINJHQwMTE3NDQxMTgyMRoUCgJiWhIOcG10U3RyQXNzZXRJZEIaCAoCYmESAiRhGggKAmJiEgIkaRoLCgJiYxIFJGYwXzIaFQoCYmQSD3R1cGxlU2VuZEJldHRlchoSCgJiZRIMZ2V0QXNzZXRJbmZvGg4KAmJmEghzdHJpbmdJZBoKCgJiZxIEaW5mbxoNCgJiaBIHc3VzcGVuZBoLCgJiaRIFY2F1c2UaEwoCYmoSDXRocm93SXNBY3RpdmUaDgoCYmsSCGlzQWN0aXZlGhEKAmJsEgtpc0FkbWluQ2FsbBoRCgJibRILdGhyb3dBc3NldHMaFQoCYm4SD3Rocm93T25lUGF5bWVudBoXCgJibxIRc3VzcGVuZFN1c3BpY2lvdXMaFAoCYnASDnRocm93VGhyZXNob2xkGg8KAmJxEgl0aHJlc2hvbGQaDQoCYnISB2Ftb3VudEEaDQoCYnMSB2Ftb3VudEIaHgoCYnQSGGNhbGNTdGFraW5nRnVuY0FuZEFkZHJlcxoLCgJidRIFc3Rha2UaFwoCYnYSEWNhbGNTdGFraW5nUGFyYW1zGgwKAmJ3EgZhbW91bnQaEQoCYngSCyR0MDkzNjI5NDI4GgoKAmJ5EgRjYWxsGhEKAmJ6EgtzdGFraW5nQWRkchoMCgFjEgdrQWN0aXZlGhIKAmNBEgxwbXRBc3NldE5hbWUaEQoCY0ISC3BtdERlY2ltYWxzGhUKAmNDEg9wbXRNaW5UaHJlc2hvbGQaIwoCY0QSHXRocmVzaG9sZFZhbHVlRm9yTWluVG9sZXJhbmNlGg8KAmNFEgl0b2xlcmFuY2UaIgoCY0YSHHNsaXBwYWdlVmFsdWVNaW5Gb3JSZXBsZW5pc2gaIgoCY0cSHHNsaXBwYWdlVmFsdWVNYXhGb3JSZXBsZW5pc2gaHQoCY0gSF3NsaXBwYWdlVmFsdWVNaW5Gb3JTd2FwGhMKAmNJEg0kdDAxODA0MTE4NjgzGhcKAmNKEhF2aXJ0dWFsUmVwbGVuaXNoQRoXCgJjSxIRdmlydHVhbFJlcGxlbmlzaEIaFwoCY0wSEWJhbGFuY2VBZnRlclN3YXBBGhcKAmNNEhFiYWxhbmNlQWZ0ZXJTd2FwQhoRCgJjThILbmV3QmFsYW5jZUEaEQoCY08SC25ld0JhbGFuY2VCGhIKAmNQEgxpbnZhcmlhbnROZXcaKwoCY1ESJXJhdGlvVmlydHVhbEJhbGFuY2VUb1ZpcnR1YWxSZXBsZW5pc2gaIwoCY1ISHXNoYXJlVG9rZW5Ub1BheUFtb3VudEFmdGVyRmVlGiAKAmNTEhpzaGFyZVRva2VuR292ZXJuYW5jZVJld2FyZBocCgJjVBIWZ292ZXJuYW5jZVJld2FyZFRva2VuQRocCgJjVRIWZ292ZXJuYW5jZVJld2FyZFRva2VuQhoTCgJjVhINJHQwMjAzOTQyMDY4ORoRCgJjVxILc3Rha2VBbW91bnQaEwoCY1gSDXVuc3Rha2VBbW91bnQaEgoCY1kSDHVuc3Rha2VBc3NldBoTCgJjWhINJHQwMjE5NzYyMjA1MRoTCgJjYRINcG10QXNzZXROYW1lQhoSCgJjYhIMcG10RGVjaW1hbHNCGg8KAmNjEglzaGFyZU5hbWUaFgoCY2QSEHNoYXJlRGVzY3JpcHRpb24aEwoCY2USDXNoYXJlRGVjaW1hbHMaGAoCY2YSEnNoYXJlSW5pdGlhbFN1cHBseRoQCgJjZxIKc2hhcmVJc3N1ZRoSCgJjaBIMc2hhcmVJc3N1ZUlkGhkKAmNpEhNpbnZhcmlhbnRDYWxjdWxhdGVkGgwKAmNqEgZzdGFrZTEaDAoCY2sSBnN0YWtlMhoZCgJjbBITcmF0aW9TaGFyZVRva2Vuc0luQRoZCgJjbRITcmF0aW9TaGFyZVRva2Vuc0luQhoTCgJjbhINJHQwMTQ0NjkxNDU0NhoTCgJjbxINJHQwMTQ1NTExNDY2OBoTCgJjcBINJHQwMTQ2NzMxNTE3NxoJCgJjcRIDcG10GgwKAmNyEgZjaGFuZ2UaEwoCY3MSDWNoYW5nZUFzc2V0SWQaFQoCY3QSD3NoYXJlVG9rZW5SYXRpbxobCgJjdRIVc2hhcmVUb2tlblRvUGF5QW1vdW50GhkKAmN2EhN2aXJ0dWFsU3dhcFRva2VuUGF5GhkKAmN3EhN2aXJ0dWFsU3dhcFRva2VuR2V0GhMKAmN4Eg0kdDAxNjkxMDE2OTg1GhMKAmN5Eg0kdDAxNjk5MDE3MDYzGhMKAmN6Eg1wbXRTdHJBc3NldElkGg4KAWQSCWtBc3NldElkQRoICgJkQRICdHgaDAoCZEISBnZlcmlmeRoZCgJkQxITbXVsdGlTaWduZWRCeUFkbWlucxoYCgJkRBISYWRtaW5QdWJLZXkxU2lnbmVkGhgKAmRFEhJhZG1pblB1YktleTJTaWduZWQaGAoCZEYSEmFkbWluUHViS2V5M1NpZ25lZBoZCgJkRxITY2FsbFRha2VJbnRvQWNjb3VudBoTCgJkSBINc2lnbmVkQnlBZG1pbhoSCgJkYRIMYW1vdW50VG9QYXlBGhIKAmRiEgxhbW91bnRUb1BheUIaHgoCZGMSGGVzdGltYXRlZEFtb3VudFRvUmVjZWl2ZRoTCgJkZBINJHQwMjM2MDIyMzY3NxoTCgJkZRINJHQwMjQzNjMyNDQ3ORoSCgJkZhIMYmFsYW5jZVJhdGlvGg4KAmRnEghwbXRSYXRpbxoRCgJkaBILc2VuZEFzc2V0SWQaEQoCZGkSC2ZlZURpc2NvdW50GhYKAmRqEhBnb3Zlcm5hbmNlUmV3YXJkGhQKAmRrEg5hbW91bnRNaW51c0ZlZRoTCgJkbBINJHQwMjUyMzQyNTUxMhoZCgJkbRITZEFwcFRocmVzaG9sZEFtb3VudBoTCgJkbhINJHQwMjU4MzEyNTkwNBoTCgJkbxINJHQwMjU5MjEyNTk5OBoUCgJkcBIOc2VuZFN0ckFzc2V0SWQaEwoCZHESDXNlbmRBc3NldE5hbWUaEgoCZHISDHNlbmREZWNpbWFscxoTCgJkcxINYW1vdW50RW5yb2xsQRoTCgJkdBINYW1vdW50RW5yb2xsQhoTCgJkdRINYXNzZXRJZFN0cmluZxoTCgJkdhINJHQwMjkwNDEyOTE0NBoKCgJkdxIEYWRkchoMCgJkeBIGcGFyYW1zGg4KAmR5EghwYXltZW50cxoJCgJkehIDaW52Gg4KAWUSCWtBc3NldElkQhoOCgFmEglrQmFsYW5jZUEaDgoBZxIJa0JhbGFuY2VCGhIKAWgSDWtTaGFyZUFzc2V0SWQaFgoBaRIRa1NoYXJlQXNzZXRTdXBwbHkaCQoBahIEa0ZlZRoPCgFrEgprSW52YXJpYW50GgsKAWwSBmtDYXVzZRoRCgFtEgxrVVNETkFkZHJlc3MaEQoBbhIMa0VVUk5BZGRyZXNzGg8KAW8SCmtEaXNjb3VudHMaFAoBcBIPa0Rpc2NvdW50VmFsdWVzGhMKAXESDmtVc2VyU3dvcEluR292GhIKAXISDWtBZG1pblB1YktleTEaEgoBcxINa0FkbWluUHViS2V5MhoSCgF0Eg1rQWRtaW5QdWJLZXkzGhcKAXUSEmtBZG1pbkludm9rZVB1YktleRoVCgF2EhBrTW9uZXlCb3hBZGRyZXNzGhAKAXcSC2tHb3ZBZGRyZXNzGgsKAXgSBm9yYWNsZRoYCgF5EhNnZXRCYXNlNThGcm9tT3JhY2xlGggKAXoSA2tleQAAAFYAAAAAAWECAAAABTIuMC4wAAAAAAFiAgAAAAd2ZXJzaW9uAAAAAAFjAgAAAAZhY3RpdmUAAAAAAWQCAAAACkFfYXNzZXRfaWQAAAAAAWUCAAAACkJfYXNzZXRfaWQAAAAAAWYCAAAAD0FfYXNzZXRfYmFsYW5jZQAAAAABZwIAAAAPQl9hc3NldF9iYWxhbmNlAAAAAAFoAgAAAA5zaGFyZV9hc3NldF9pZAAAAAABaQIAAAASc2hhcmVfYXNzZXRfc3VwcGx5AAAAAAFqAgAAAApjb21taXNzaW9uAAAAAAFrAgAAAAlpbnZhcmlhbnQAAAAAAWwCAAAADnNodXRkb3duX2NhdXNlAAAAAAFtAgAAABhzdGFraW5nX3VzZG5uc2J0X2FkZHJlc3MAAAAAAW4CAAAAFHN0YWtpbmdfZXVybl9hZGRyZXNzAAAAAAFvAgAAAAlkaXNjb3VudHMAAAAAAXACAAAAD2Rpc2NvdW50X3ZhbHVlcwAAAAABcQIAAAAMX1NXT1BfYW1vdW50AAAAAAFyAgAAAAthZG1pbl9wdWJfMQAAAAABcwIAAAALYWRtaW5fcHViXzIAAAAAAXQCAAAAC2FkbWluX3B1Yl8zAAAAAAF1AgAAABBhZG1pbl9pbnZva2VfcHViAAAAAAF2AgAAABFtb25leV9ib3hfYWRkcmVzcwAAAAABdwIA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", "height": 2084512, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: sRVmQR5UUJKRKZCf1TQfzRMKNNSybvkhGumCVmFFztf Next: HHTretVGkLmUGNcuYk3CNk53GFLEPycsdjonWAA4DDut Diff:
OldNewDifferences
133133
134134 let digits8 = 8
135135
136-let dAppThreshold = 50
136+let dAppThreshold = 125
137137
138-let dAppThresholdScale2 = 100
138+let dAppThresholdScale2 = 1000
139139
140-let exchangeRatioLimitMin = 90000000
140+let exchangeRatioLimitCoef = 2500000
141141
142-let exchangeRatioLimitMax = 110000000
142+let exchangeRatioLimit = 93500000
143143
144144 let alpha = 50
145145
310310 func throwOnePayment () = throw("One attached payment expected")
311311
312312
313-func throwThreshold (threshold,amountA,amountB) = throw(((((((((("New balance in assets of the DApp is less than threshold " + toString(threshold)) + ": ") + toString(amountA)) + " ") + assetNameA) + ", ") + toString(amountB)) + " ") + assetNameB))
313+func suspendSuspicious () = suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB) + ". State: ") + toString(accountBalance(assetIdA))) + " ") + assetNameA) + ", ") + toString(accountBalance(assetIdB))) + " ") + assetNameB))
314314
315315
316-func suspendSuspicious () = suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB) + ". State: ") + toString(accountBalance(assetIdA))) + " ") + assetNameA) + ", ") + toString(accountBalance(assetIdB))) + " ") + assetNameB))
316+func throwThreshold (threshold,amountA,amountB) = throw(((((((((("New balance in assets of the DApp is less than threshold " + toString(threshold)) + ": ") + toString(amountA)) + " ") + assetNameA) + ", ") + toString(amountB)) + " ") + assetNameB))
317317
318318
319319 func calcStakingFuncAndAddres (stake,assetId) = if (stake)
323323
324324 func calcStakingParams (stake,amount,assetId) = if (stake)
325325 then {
326- let $t093469412 = calcStakingFuncAndAddres(stake, assetId)
327- let call = $t093469412._1
328- let stakingAddr = $t093469412._2
326+ let $t093629428 = calcStakingFuncAndAddres(stake, assetId)
327+ let call = $t093629428._1
328+ let stakingAddr = $t093629428._2
329329 $Tuple4(call, stakingAddr, nil, [AttachedPayment(assetId, amount)])
330330 }
331331 else {
332- let $t094989564 = calcStakingFuncAndAddres(stake, assetId)
333- let call = $t094989564._1
334- let stakingAddr = $t094989564._2
332+ let $t095149580 = calcStakingFuncAndAddres(stake, assetId)
333+ let call = $t095149580._1
334+ let stakingAddr = $t095149580._2
335335 $Tuple4(call, stakingAddr, [amount, toBase58String(assetId)], nil)
336336 }
337337
362362 }
363363
364364
365+func calcBalanceAndPmtRatio (ABalance,BBalance,minAmountToReceive,pmtAmount,pmtAssetId) = if ((balanceA > balanceB))
366+ then {
367+ let ratio = fraction(scale8, balanceA, balanceB)
368+ let pratio = if ((pmtAssetId == assetIdA))
369+ then fraction(scale8, minAmountToReceive, pmtAmount)
370+ else fraction(scale8, minAmountToReceive, pmtAmount)
371+ $Tuple2(ratio, pratio)
372+ }
373+ else {
374+ let ratio = fraction(scale8, balanceB, balanceA)
375+ let pratio = if ((pmtAssetId == assetIdA))
376+ then fraction(scale8, minAmountToReceive, pmtAmount)
377+ else fraction(scale8, minAmountToReceive, pmtAmount)
378+ $Tuple2(ratio, pratio)
379+ }
380+
381+
365382 @Callable(i)
366383 func init () = {
367- let $t01073610813 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
368- let pmtAmountA = $t01073610813._1
369- let pmtAssetIdA = $t01073610813._2
370- let $t01081810895 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
371- let pmtAmountB = $t01081810895._1
372- let pmtAssetIdB = $t01081810895._2
373- let $t01090010977 = getAssetInfo(pmtAssetIdA)
374- let pmtStrAssetIdA = $t01090010977._1
375- let pmtAssetNameA = $t01090010977._2
376- let pmtDecimalsA = $t01090010977._3
377- let $t01098211059 = getAssetInfo(pmtAssetIdB)
378- let pmtStrAssetIdB = $t01098211059._1
379- let pmtAssetNameB = $t01098211059._2
380- let pmtDecimalsB = $t01098211059._3
384+ let $t01149811575 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
385+ let pmtAmountA = $t01149811575._1
386+ let pmtAssetIdA = $t01149811575._2
387+ let $t01158011657 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
388+ let pmtAmountB = $t01158011657._1
389+ let pmtAssetIdB = $t01158011657._2
390+ let $t01166211739 = getAssetInfo(pmtAssetIdA)
391+ let pmtStrAssetIdA = $t01166211739._1
392+ let pmtAssetNameA = $t01166211739._2
393+ let pmtDecimalsA = $t01166211739._3
394+ let $t01174411821 = getAssetInfo(pmtAssetIdB)
395+ let pmtStrAssetIdB = $t01174411821._1
396+ let pmtAssetNameB = $t01174411821._2
397+ let pmtDecimalsB = $t01174411821._3
381398 if (isDefined(getBoolean(this, kActive)))
382399 then throwIsActive()
383400 else if ((pmtAssetIdA == pmtAssetIdB))
414431 let pmtAssetIdB = i.payments[1].assetId
415432 let ratioShareTokensInA = fraction(scale8, i.payments[0].amount, balanceA)
416433 let ratioShareTokensInB = fraction(scale8, i.payments[1].amount, balanceB)
417- let $t01370713784 = getAssetInfo(pmtAssetIdA)
418- let pmtStrAssetIdA = $t01370713784._1
419- let pmtAssetNameA = $t01370713784._2
420- let pmtDecimalsA = $t01370713784._3
421- let $t01378913906 = getAssetInfo(pmtAssetIdB)
422- let pmtStrAssetIdB = $t01378913906._1
423- let pmtAssetNameB = $t01378913906._2
424- let pmtDecimalsB = $t01378913906._3
425- let $t01391114415 = if ((ratioShareTokensInB > ratioShareTokensInA))
434+ let $t01446914546 = getAssetInfo(pmtAssetIdA)
435+ let pmtStrAssetIdA = $t01446914546._1
436+ let pmtAssetNameA = $t01446914546._2
437+ let pmtDecimalsA = $t01446914546._3
438+ let $t01455114668 = getAssetInfo(pmtAssetIdB)
439+ let pmtStrAssetIdB = $t01455114668._1
440+ let pmtAssetNameB = $t01455114668._2
441+ let pmtDecimalsB = $t01455114668._3
442+ let $t01467315177 = if ((ratioShareTokensInB > ratioShareTokensInA))
426443 then {
427444 let pmt = fraction(balanceB, ratioShareTokensInA, scale8, CEILING)
428445 $Tuple5(i.payments[0].amount, pmt, (i.payments[1].amount - pmt), pmtAssetIdB, ratioShareTokensInA)
431448 let pmt = fraction(balanceA, ratioShareTokensInB, scale8, CEILING)
432449 $Tuple5(pmt, i.payments[1].amount, (i.payments[0].amount - pmt), pmtAssetIdA, ratioShareTokensInB)
433450 }
434- let pmtAmountA = $t01391114415._1
435- let pmtAmountB = $t01391114415._2
436- let change = $t01391114415._3
437- let changeAssetId = $t01391114415._4
438- let shareTokenRatio = $t01391114415._5
451+ let pmtAmountA = $t01467315177._1
452+ let pmtAmountB = $t01467315177._2
453+ let change = $t01467315177._3
454+ let changeAssetId = $t01467315177._4
455+ let shareTokenRatio = $t01467315177._5
439456 let shareTokenToPayAmount = fraction(shareTokenRatio, shareAssetSupply, scale8)
440457 if ((size(i.payments) != 2))
441458 then throw("Two attached assets expected")
470487
471488 @Callable(i)
472489 func replenishWithOneToken (virtualSwapTokenPay,virtualSwapTokenGet) = valueOrElse(isActive(), {
473- let $t01614816223 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
474- let pmtAmount = $t01614816223._1
475- let pmtAssetId = $t01614816223._2
476- let $t01622816301 = getAssetInfo(pmtAssetId)
477- let pmtStrAssetId = $t01622816301._1
478- let pmtAssetName = $t01622816301._2
479- let pmtDecimals = $t01622816301._3
490+ let $t01691016985 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
491+ let pmtAmount = $t01691016985._1
492+ let pmtAssetId = $t01691016985._2
493+ let $t01699017063 = getAssetInfo(pmtAssetId)
494+ let pmtStrAssetId = $t01699017063._1
495+ let pmtAssetName = $t01699017063._2
496+ let pmtDecimals = $t01699017063._3
480497 let pmtMinThreshold = 5000000
481498 let thresholdValueForMinTolerance = 50000000
482499 let tolerance = if ((thresholdValueForMinTolerance > pmtAmount))
496513 else false)
497514 then throwAssets()
498515 else {
499- let $t01727917921 = if ((pmtAssetId == assetIdA))
516+ let $t01804118683 = if ((pmtAssetId == assetIdA))
500517 then $Tuple6((pmtAmount - virtualSwapTokenPay), virtualSwapTokenGet, (balanceA + virtualSwapTokenPay), (balanceB - virtualSwapTokenGet), (balanceA + pmtAmount), balanceB)
501518 else $Tuple6(virtualSwapTokenGet, (pmtAmount - virtualSwapTokenPay), (balanceA - virtualSwapTokenGet), (balanceB + virtualSwapTokenPay), balanceA, (balanceB + pmtAmount))
502- let virtualReplenishA = $t01727917921._1
503- let virtualReplenishB = $t01727917921._2
504- let balanceAfterSwapA = $t01727917921._3
505- let balanceAfterSwapB = $t01727917921._4
506- let newBalanceA = $t01727917921._5
507- let newBalanceB = $t01727917921._6
519+ let virtualReplenishA = $t01804118683._1
520+ let virtualReplenishB = $t01804118683._2
521+ let balanceAfterSwapA = $t01804118683._3
522+ let balanceAfterSwapB = $t01804118683._4
523+ let newBalanceA = $t01804118683._5
524+ let newBalanceB = $t01804118683._6
508525 let invariantNew = invariantCalc(balanceAfterSwapA, balanceAfterSwapB)
509526 let ratioVirtualBalanceToVirtualReplenish = (fraction(scale16, balanceAfterSwapA, balanceAfterSwapB) / fraction(scale8, virtualReplenishA, virtualReplenishB))
510- let dAppThresholdAmount = fraction((newBalanceA + newBalanceB), dAppThreshold, (2 * dAppThresholdScale2))
511527 if (if ((slippageValueMinForSwap >= fraction(scale8, invariant, invariantNew)))
512528 then true
513529 else (invariant > invariantNew))
516532 then true
517533 else (ratioVirtualBalanceToVirtualReplenish > slippageValueMaxForReplenish))
518534 then throw("Swap with virtualSwapTokenPay and virtualSwapTokenGet is possible, but ratio after virtual swap is incorrect")
519- else if (if ((dAppThresholdAmount > newBalanceA))
520- then true
521- else (dAppThresholdAmount > newBalanceB))
522- then throwThreshold(dAppThresholdAmount, newBalanceA, newBalanceB)
523- else {
524- let ratioShareTokensInA = fraction(virtualReplenishA, scale8, balanceAfterSwapA)
525- let ratioShareTokensInB = fraction(virtualReplenishB, scale8, balanceAfterSwapB)
526- let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scale8)
527- let shareTokenToPayAmountAfterFee = fraction(shareTokenToPayAmount, (feeScale6 - (fee / 2)), feeScale6)
528- let shareTokenGovernanceReward = fraction(shareTokenToPayAmount, (feeGovernance / 2), feeScale6)
529- let governanceRewardTokenA = fraction(shareTokenGovernanceReward, balanceA, shareAssetSupply)
530- let governanceRewardTokenB = fraction(shareTokenGovernanceReward, balanceB, shareAssetSupply)
531- let $t01990820203 = if ((pmtStrAssetId == strAssetIdA))
532- then $Tuple3((pmtAmount - governanceRewardTokenA), governanceRewardTokenB, strAssetIdB)
533- else $Tuple3((pmtAmount - governanceRewardTokenB), governanceRewardTokenA, strAssetIdA)
534- let stakeAmount = $t01990820203._1
535- let unstakeAmount = $t01990820203._2
536- let unstakeAsset = $t01990820203._3
537- let stake1 = if (containsElement(stakingAssets, pmtStrAssetId))
538- then invoke(this, "stakeUnstake", [true, stakeAmount, pmtStrAssetId], nil)
539- else 0
540- if ((stake1 == stake1))
541- then {
542- let stake2 = if (containsElement(stakingAssets, unstakeAsset))
543- then invoke(this, "stakeUnstake", [false, unstakeAmount, unstakeAsset], nil)
544- else 0
545- if ((stake2 == stake2))
546- then [Reissue(shareAssetId, shareTokenToPayAmountAfterFee, true), ScriptTransfer(i.caller, shareTokenToPayAmountAfterFee, shareAssetId), ScriptTransfer(moneyBoxAddress, governanceRewardTokenA, assetIdA), ScriptTransfer(moneyBoxAddress, governanceRewardTokenB, assetIdB), IntegerEntry(kBalanceA, (newBalanceA - governanceRewardTokenA)), IntegerEntry(kBalanceB, (newBalanceB - governanceRewardTokenB)), IntegerEntry(kShareAssetSupply, (shareAssetSupply + shareTokenToPayAmountAfterFee)), IntegerEntry(kInvariant, invariantCalc((newBalanceA - governanceRewardTokenA), (newBalanceB - governanceRewardTokenB)))]
547- else throw("Strict value is not equal to itself.")
548- }
549- else throw("Strict value is not equal to itself.")
550- }
535+ else {
536+ let ratioShareTokensInA = fraction(virtualReplenishA, scale8, balanceAfterSwapA)
537+ let ratioShareTokensInB = fraction(virtualReplenishB, scale8, balanceAfterSwapB)
538+ let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scale8)
539+ let shareTokenToPayAmountAfterFee = fraction(shareTokenToPayAmount, (feeScale6 - (fee / 2)), feeScale6)
540+ let shareTokenGovernanceReward = fraction(shareTokenToPayAmount, (feeGovernance / 2), feeScale6)
541+ let governanceRewardTokenA = fraction(shareTokenGovernanceReward, balanceA, shareAssetSupply)
542+ let governanceRewardTokenB = fraction(shareTokenGovernanceReward, balanceB, shareAssetSupply)
543+ let $t02039420689 = if ((pmtStrAssetId == strAssetIdA))
544+ then $Tuple3((pmtAmount - governanceRewardTokenA), governanceRewardTokenB, strAssetIdB)
545+ else $Tuple3((pmtAmount - governanceRewardTokenB), governanceRewardTokenA, strAssetIdA)
546+ let stakeAmount = $t02039420689._1
547+ let unstakeAmount = $t02039420689._2
548+ let unstakeAsset = $t02039420689._3
549+ let stake1 = if (containsElement(stakingAssets, pmtStrAssetId))
550+ then invoke(this, "stakeUnstake", [true, stakeAmount, pmtStrAssetId], nil)
551+ else 0
552+ if ((stake1 == stake1))
553+ then {
554+ let stake2 = if (containsElement(stakingAssets, unstakeAsset))
555+ then invoke(this, "stakeUnstake", [false, unstakeAmount, unstakeAsset], nil)
556+ else 0
557+ if ((stake2 == stake2))
558+ then [Reissue(shareAssetId, shareTokenToPayAmountAfterFee, true), ScriptTransfer(i.caller, shareTokenToPayAmountAfterFee, shareAssetId), ScriptTransfer(moneyBoxAddress, governanceRewardTokenA, assetIdA), ScriptTransfer(moneyBoxAddress, governanceRewardTokenB, assetIdB), IntegerEntry(kBalanceA, (newBalanceA - governanceRewardTokenA)), IntegerEntry(kBalanceB, (newBalanceB - governanceRewardTokenB)), IntegerEntry(kShareAssetSupply, (shareAssetSupply + shareTokenToPayAmountAfterFee)), IntegerEntry(kInvariant, invariantCalc((newBalanceA - governanceRewardTokenA), (newBalanceB - governanceRewardTokenB)))]
559+ else throw("Strict value is not equal to itself.")
560+ }
561+ else throw("Strict value is not equal to itself.")
562+ }
551563 }
552564 })
553565
555567
556568 @Callable(i)
557569 func withdraw () = valueOrElse(isActive(), {
558- let $t02149021565 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
559- let pmtAmount = $t02149021565._1
560- let pmtAssetId = $t02149021565._2
570+ let $t02197622051 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
571+ let pmtAmount = $t02197622051._1
572+ let pmtAssetId = $t02197622051._2
561573 let amountToPayA = fraction(pmtAmount, balanceA, shareAssetSupply)
562574 let amountToPayB = fraction(pmtAmount, balanceB, shareAssetSupply)
563575 let invariantCalculated = invariantCalc((balanceA - amountToPayA), (balanceB - amountToPayB))
588600
589601 @Callable(i)
590602 func exchange (estimatedAmountToReceive,minAmountToReceive) = valueOrElse(isActive(), {
591- let $t02311623191 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
592- let pmtAmount = $t02311623191._1
593- let pmtAssetId = $t02311623191._2
603+ let $t02360223677 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
604+ let pmtAmount = $t02360223677._1
605+ let pmtAssetId = $t02360223677._2
594606 if ((0 >= estimatedAmountToReceive))
595607 then throw(("Estimated amount must be positive. Actual: " + toString(estimatedAmountToReceive)))
596608 else if ((minAmountToReceive > estimatedAmountToReceive))
605617 then throwAssets()
606618 else if ((10000000 > pmtAmount))
607619 then throw("Only swap of 10.000000 or more tokens is allowed")
608- else if (if ((exchangeRatioLimitMin > fraction(scale8, minAmountToReceive, pmtAmount)))
609- then true
610- else (fraction(scale8, estimatedAmountToReceive, pmtAmount) > exchangeRatioLimitMax))
611- then throw("Incorrect args and pmt ratio")
612- else {
613- let sendAssetId = if ((pmtAssetId == assetIdA))
614- then assetIdB
615- else assetIdA
616- let amount = calculateSendAmount(estimatedAmountToReceive, minAmountToReceive, pmtAmount, pmtAssetId)
617- let feeDiscount = calculateFeeDiscount(i.originCaller)
618- let governanceReward = fraction(amount, fraction(feeGovernance, feeDiscount, feeScale6, CEILING), feeScale6)
619- let amountMinusFee = fraction(amount, (feeScale6 - fraction(fee, feeDiscount, feeScale6, CEILING)), feeScale6)
620- let $t02464424906 = if ((pmtAssetId == assetIdA))
621- then $Tuple2((balanceA + pmtAmount), ((balanceB - amountMinusFee) - governanceReward))
622- else $Tuple2(((balanceA - amountMinusFee) - governanceReward), (balanceB + pmtAmount))
623- let newBalanceA = $t02464424906._1
624- let newBalanceB = $t02464424906._2
625- let dAppThresholdAmount = fraction((newBalanceA + newBalanceB), dAppThreshold, (2 * dAppThresholdScale2))
626- if (if ((dAppThresholdAmount > newBalanceA))
627- then true
628- else (dAppThresholdAmount > newBalanceB))
629- then throwThreshold(dAppThresholdAmount, newBalanceA, newBalanceB)
630- else {
631- let $t02520525278 = getAssetInfo(pmtAssetId)
632- let pmtStrAssetId = $t02520525278._1
633- let pmtAssetName = $t02520525278._2
634- let pmtDecimals = $t02520525278._3
635- let $t02529125368 = getAssetInfo(sendAssetId)
636- let sendStrAssetId = $t02529125368._1
637- let sendAssetName = $t02529125368._2
638- let sendDecimals = $t02529125368._3
639- let stake1 = if (containsElement(stakingAssets, pmtStrAssetId))
640- then invoke(this, "stakeUnstake", [true, pmtAmount, pmtStrAssetId], nil)
641- else 0
642- if ((stake1 == stake1))
643- then {
644- let stake2 = if (containsElement(stakingAssets, sendStrAssetId))
645- then invoke(this, "stakeUnstake", [false, (amountMinusFee + governanceReward), sendStrAssetId], nil)
646- else 0
647- if ((stake2 == stake2))
648- then $Tuple2([IntegerEntry(kBalanceA, newBalanceA), IntegerEntry(kBalanceB, newBalanceB), IntegerEntry(kInvariant, invariantCalc(newBalanceA, newBalanceB)), ScriptTransfer(i.caller, amountMinusFee, sendAssetId), ScriptTransfer(moneyBoxAddress, governanceReward, sendAssetId)], $Tuple2(amountMinusFee, sendAssetId))
649- else throw("Strict value is not equal to itself.")
650- }
651- else throw("Strict value is not equal to itself.")
652- }
653- }
620+ else {
621+ let $t02436324479 = calcBalanceAndPmtRatio(balanceA, balanceB, minAmountToReceive, pmtAmount, pmtAssetId)
622+ let balanceRatio = $t02436324479._1
623+ let pmtRatio = $t02436324479._2
624+ if (((exchangeRatioLimit - fraction(exchangeRatioLimitCoef, balanceRatio, scale8)) > pmtRatio))
625+ then throw("Incorrect args and pmt ratio")
626+ else {
627+ let sendAssetId = if ((pmtAssetId == assetIdA))
628+ then assetIdB
629+ else assetIdA
630+ let amount = calculateSendAmount(estimatedAmountToReceive, minAmountToReceive, pmtAmount, pmtAssetId)
631+ let feeDiscount = calculateFeeDiscount(i.originCaller)
632+ let governanceReward = fraction(amount, fraction(feeGovernance, feeDiscount, feeScale6, CEILING), feeScale6)
633+ let amountMinusFee = fraction(amount, (feeScale6 - fraction(fee, feeDiscount, feeScale6, CEILING)), feeScale6)
634+ let $t02523425512 = if ((pmtAssetId == assetIdA))
635+ then $Tuple2((balanceA + pmtAmount), ((balanceB - amountMinusFee) - governanceReward))
636+ else $Tuple2(((balanceA - amountMinusFee) - governanceReward), (balanceB + pmtAmount))
637+ let newBalanceA = $t02523425512._1
638+ let newBalanceB = $t02523425512._2
639+ let dAppThresholdAmount = fraction((newBalanceA + newBalanceB), dAppThreshold, (2 * dAppThresholdScale2))
640+ if (if ((dAppThresholdAmount > newBalanceA))
641+ then true
642+ else (dAppThresholdAmount > newBalanceB))
643+ then throwThreshold(dAppThresholdAmount, newBalanceA, newBalanceB)
644+ else {
645+ let $t02583125904 = getAssetInfo(pmtAssetId)
646+ let pmtStrAssetId = $t02583125904._1
647+ let pmtAssetName = $t02583125904._2
648+ let pmtDecimals = $t02583125904._3
649+ let $t02592125998 = getAssetInfo(sendAssetId)
650+ let sendStrAssetId = $t02592125998._1
651+ let sendAssetName = $t02592125998._2
652+ let sendDecimals = $t02592125998._3
653+ let stake1 = if (containsElement(stakingAssets, pmtStrAssetId))
654+ then invoke(this, "stakeUnstake", [true, pmtAmount, pmtStrAssetId], nil)
655+ else 0
656+ if ((stake1 == stake1))
657+ then {
658+ let stake2 = if (containsElement(stakingAssets, sendStrAssetId))
659+ then invoke(this, "stakeUnstake", [false, (amountMinusFee + governanceReward), sendStrAssetId], nil)
660+ else 0
661+ if ((stake2 == stake2))
662+ then $Tuple2([IntegerEntry(kBalanceA, newBalanceA), IntegerEntry(kBalanceB, newBalanceB), IntegerEntry(kInvariant, invariantCalc(newBalanceA, newBalanceB)), ScriptTransfer(i.caller, amountMinusFee, sendAssetId), ScriptTransfer(moneyBoxAddress, governanceReward, sendAssetId)], $Tuple2(amountMinusFee, sendAssetId))
663+ else throw("Strict value is not equal to itself.")
664+ }
665+ else throw("Strict value is not equal to itself.")
666+ }
667+ }
668+ }
654669 })
655670
656671
711726 func stakeUnstake (stake,amount,assetIdString) = if ((i.caller != this))
712727 then throw("Only contract itself can invoke this function")
713728 else {
714- let $t02837228475 = calcStakingParams(stake, amount, fromBase58String(assetIdString))
715- let call = $t02837228475._1
716- let addr = $t02837228475._2
717- let params = $t02837228475._3
718- let payments = $t02837228475._4
729+ let $t02904129144 = calcStakingParams(stake, amount, fromBase58String(assetIdString))
730+ let call = $t02904129144._1
731+ let addr = $t02904129144._2
732+ let params = $t02904129144._3
733+ let payments = $t02904129144._4
719734 let inv = invoke(addr, call, params, payments)
720735 if ((inv == inv))
721736 then nil
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let version = "2.0.0"
55
66 let kVersion = "version"
77
88 let kActive = "active"
99
1010 let kAssetIdA = "A_asset_id"
1111
1212 let kAssetIdB = "B_asset_id"
1313
1414 let kBalanceA = "A_asset_balance"
1515
1616 let kBalanceB = "B_asset_balance"
1717
1818 let kShareAssetId = "share_asset_id"
1919
2020 let kShareAssetSupply = "share_asset_supply"
2121
2222 let kFee = "commission"
2323
2424 let kInvariant = "invariant"
2525
2626 let kCause = "shutdown_cause"
2727
2828 let kUSDNAddress = "staking_usdnnsbt_address"
2929
3030 let kEURNAddress = "staking_eurn_address"
3131
3232 let kDiscounts = "discounts"
3333
3434 let kDiscountValues = "discount_values"
3535
3636 let kUserSwopInGov = "_SWOP_amount"
3737
3838 let kAdminPubKey1 = "admin_pub_1"
3939
4040 let kAdminPubKey2 = "admin_pub_2"
4141
4242 let kAdminPubKey3 = "admin_pub_3"
4343
4444 let kAdminInvokePubKey = "admin_invoke_pub"
4545
4646 let kMoneyBoxAddress = "money_box_address"
4747
4848 let kGovAddress = "governance_address"
4949
5050 let oracle = Address(base58'3NBBWfzZtZtszaXbitTKnrB2xXwv26Bn7H9')
5151
5252 func getBase58FromOracle (key) = match getString(oracle, key) {
5353 case string: String =>
5454 fromBase58String(string)
5555 case nothing =>
5656 throw((key + "is empty"))
5757 }
5858
5959
6060 let adminPubKey1 = getBase58FromOracle(kAdminPubKey1)
6161
6262 let adminPubKey2 = getBase58FromOracle(kAdminPubKey2)
6363
6464 let adminPubKey3 = getBase58FromOracle(kAdminPubKey3)
6565
6666 let adminPubKeyInvoke = getBase58FromOracle(kAdminInvokePubKey)
6767
6868 let moneyBoxAddress = Address(getBase58FromOracle(kMoneyBoxAddress))
6969
7070 let govAddress = Address(getBase58FromOracle(kGovAddress))
7171
7272 let stakingUSDNAddress = Address(getBase58FromOracle(kUSDNAddress))
7373
7474 let USDN = base58'8UrfDVd5GreeUwm7uPk7eYz1eMv376kzR52C6sANPkwS'
7575
7676 let stakingAssets = [toBase58String(USDN)]
7777
7878 let active = getBooleanValue(this, kActive)
7979
8080 let strAssetIdA = getStringValue(this, kAssetIdA)
8181
8282 let strAssetIdB = getStringValue(this, kAssetIdB)
8383
8484 let assetIdA = if ((strAssetIdA == "WAVES"))
8585 then unit
8686 else fromBase58String(strAssetIdA)
8787
8888 let assetIdB = if ((strAssetIdB == "WAVES"))
8989 then unit
9090 else fromBase58String(strAssetIdB)
9191
9292 let assetNameA = match assetIdA {
9393 case id: ByteVector =>
9494 value(assetInfo(id)).name
9595 case waves: Unit =>
9696 "WAVES"
9797 case _ =>
9898 throw("Match error")
9999 }
100100
101101 let assetNameB = match assetIdB {
102102 case id: ByteVector =>
103103 value(assetInfo(id)).name
104104 case waves: Unit =>
105105 "WAVES"
106106 case _ =>
107107 throw("Match error")
108108 }
109109
110110 let balanceA = getIntegerValue(this, kBalanceA)
111111
112112 let balanceB = getIntegerValue(this, kBalanceB)
113113
114114 let shareAssetId = fromBase58String(getStringValue(this, kShareAssetId))
115115
116116 let shareAssetSupply = getIntegerValue(this, kShareAssetSupply)
117117
118118 let invariant = getIntegerValue(this, kInvariant)
119119
120120 let fee = getIntegerValue(this, kFee)
121121
122122 let feeGovernance = fraction(fee, 40, 100)
123123
124124 let feeScale6 = 1000000
125125
126126 let scale3 = 1000
127127
128128 let scale8 = 100000000
129129
130130 let scale16 = 10000000000000000
131131
132132 let slippageScale3 = 1000
133133
134134 let digits8 = 8
135135
136-let dAppThreshold = 50
136+let dAppThreshold = 125
137137
138-let dAppThresholdScale2 = 100
138+let dAppThresholdScale2 = 1000
139139
140-let exchangeRatioLimitMin = 90000000
140+let exchangeRatioLimitCoef = 2500000
141141
142-let exchangeRatioLimitMax = 110000000
142+let exchangeRatioLimit = 93500000
143143
144144 let alpha = 50
145145
146146 let alphaDigits = 2
147147
148148 let beta = 4600000000000000
149149
150150 func accountBalance (assetId) = match assetId {
151151 case id: ByteVector =>
152152 assetBalance(this, id)
153153 case waves: Unit =>
154154 wavesBalance(this).available
155155 case _ =>
156156 throw("Match error")
157157 }
158158
159159
160160 func stakedAmount (assetId) = {
161161 let stakedAmountCalculated = match assetId {
162162 case aId: ByteVector =>
163163 if ((aId == USDN))
164164 then getInteger(stakingUSDNAddress, ((("rpd_balance_" + toBase58String(aId)) + "_") + toString(this)))
165165 else 0
166166 case _: Unit =>
167167 0
168168 case _ =>
169169 throw("Match error")
170170 }
171171 match stakedAmountCalculated {
172172 case i: Int =>
173173 i
174174 case _ =>
175175 0
176176 }
177177 }
178178
179179
180180 let stakedAmountA = stakedAmount(assetIdA)
181181
182182 let stakedAmountB = stakedAmount(assetIdB)
183183
184184 let availableBalanceA = (balanceA - stakedAmountA)
185185
186186 let availableBalanceB = (balanceB - stakedAmountB)
187187
188188 let accountBalanceWithStakedA = (accountBalance(assetIdA) + stakedAmountA)
189189
190190 let accountBalanceWithStakedB = (accountBalance(assetIdB) + stakedAmountB)
191191
192192 let hasEnoughBalance = if ((accountBalanceWithStakedA >= balanceA))
193193 then (accountBalanceWithStakedB >= balanceB)
194194 else false
195195
196196 func skewness (x,y) = ((fraction(scale16, x, y) + fraction(scale16, y, x)) / 2)
197197
198198
199199 func invariantCalc (x,y) = {
200200 let sk = skewness(x, y)
201201 (fraction((x + y), scale16, pow(sk, digits8, alpha, alphaDigits, digits8, CEILING)) + (2 * fraction(toInt(pow(fraction(toBigInt(x), toBigInt(y), toBigInt(scale8)), 0, toBigInt(5), 1, (digits8 / 2), DOWN)), pow((sk - beta), digits8, alpha, alphaDigits, digits8, DOWN), scale8)))
202202 }
203203
204204
205205 func calculateSendAmount (amountToSendEstimated,minTokenReceiveAmount,tokenReceiveAmount,tokenId) = {
206206 let worstAllowedNewInvariantRatio = (scale16 - ((scale16 * 1) / 10000000))
207207 let deltaBetweenMaxAndMinSendValue = (amountToSendEstimated - minTokenReceiveAmount)
208208 let x = (balanceA + tokenReceiveAmount)
209209 let y = (balanceB + tokenReceiveAmount)
210210 func getStepAmount (acc,step) = if ((acc._1 == -1))
211211 then {
212212 let amountToSend = (amountToSendEstimated - (((step * deltaBetweenMaxAndMinSendValue) / 3) / scale3))
213213 let stepInvariant = if ((tokenId == assetIdA))
214214 then invariantCalc(x, (balanceB - amountToSend))
215215 else invariantCalc((balanceA - amountToSend), y)
216216 if ((stepInvariant > invariant))
217217 then $Tuple2(amountToSend, stepInvariant)
218218 else $Tuple2(-1, 0)
219219 }
220220 else acc
221221
222222 let amountToSendMin = getStepAmount($Tuple2(-1, 0), 3000)
223223 if ((0 > amountToSendMin._1))
224224 then throw("Price is worse than minReceived")
225225 else {
226226 let invEstimated = if ((tokenId == assetIdA))
227227 then invariantCalc(x, (balanceB - amountToSendEstimated))
228228 else if ((tokenId == assetIdB))
229229 then invariantCalc((balanceA - amountToSendEstimated), y)
230230 else throw("Wrong asset in payment")
231231 if ((invariant > invEstimated))
232232 then if ((worstAllowedNewInvariantRatio >= fraction(scale16, invariant, invEstimated)))
233233 then throw("The requested price is too not profitable for user")
234234 else {
235235 let a = {
236236 let $l = [25, 200, 500]
237237 let $s = size($l)
238238 let $acc0 = $Tuple2(-1, 0)
239239 func $f0_1 ($a,$i) = if (($i >= $s))
240240 then $a
241241 else getStepAmount($a, $l[$i])
242242
243243 func $f0_2 ($a,$i) = if (($i >= $s))
244244 then $a
245245 else throw("List size exceeds 3")
246246
247247 $f0_2($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3)
248248 }
249249 if ((0 > a._1))
250250 then amountToSendMin._1
251251 else a._1
252252 }
253253 else {
254254 let a = {
255255 let $l = [-500, -200, -25]
256256 let $s = size($l)
257257 let $acc0 = $Tuple2(-1, 0)
258258 func $f0_1 ($a,$i) = if (($i >= $s))
259259 then $a
260260 else getStepAmount($a, $l[$i])
261261
262262 func $f0_2 ($a,$i) = if (($i >= $s))
263263 then $a
264264 else throw("List size exceeds 3")
265265
266266 $f0_2($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3)
267267 }
268268 let tupleSendBetter = if ((0 > a._1))
269269 then $Tuple2(amountToSendEstimated, invEstimated)
270270 else a
271271 if ((worstAllowedNewInvariantRatio >= fraction(scale16, invariant, tupleSendBetter._2)))
272272 then throw("The requested price is too not profitable for user")
273273 else tupleSendBetter._1
274274 }
275275 }
276276 }
277277
278278
279279 func getAssetInfo (assetId) = match assetId {
280280 case id: ByteVector =>
281281 let stringId = toBase58String(id)
282282 let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist"))
283283 $Tuple3(stringId, info.name, info.decimals)
284284 case waves: Unit =>
285285 $Tuple3("WAVES", "WAVES", 8)
286286 case _ =>
287287 throw("Match error")
288288 }
289289
290290
291291 func suspend (cause) = [BooleanEntry(kActive, false), StringEntry(kCause, cause)]
292292
293293
294294 func throwIsActive () = throw("DApp is already active")
295295
296296
297297 func isActive () = if (active)
298298 then unit
299299 else throw("DApp is inactive at this moment")
300300
301301
302302 func isAdminCall (i) = if (containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey))
303303 then unit
304304 else throw("Only admin can call this function")
305305
306306
307307 func throwAssets () = throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB))
308308
309309
310310 func throwOnePayment () = throw("One attached payment expected")
311311
312312
313-func throwThreshold (threshold,amountA,amountB) = throw(((((((((("New balance in assets of the DApp is less than threshold " + toString(threshold)) + ": ") + toString(amountA)) + " ") + assetNameA) + ", ") + toString(amountB)) + " ") + assetNameB))
313+func suspendSuspicious () = suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB) + ". State: ") + toString(accountBalance(assetIdA))) + " ") + assetNameA) + ", ") + toString(accountBalance(assetIdB))) + " ") + assetNameB))
314314
315315
316-func suspendSuspicious () = suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB) + ". State: ") + toString(accountBalance(assetIdA))) + " ") + assetNameA) + ", ") + toString(accountBalance(assetIdB))) + " ") + assetNameB))
316+func throwThreshold (threshold,amountA,amountB) = throw(((((((((("New balance in assets of the DApp is less than threshold " + toString(threshold)) + ": ") + toString(amountA)) + " ") + assetNameA) + ", ") + toString(amountB)) + " ") + assetNameB))
317317
318318
319319 func calcStakingFuncAndAddres (stake,assetId) = if (stake)
320320 then $Tuple2("lockNeutrino", stakingUSDNAddress)
321321 else $Tuple2("unlockNeutrino", stakingUSDNAddress)
322322
323323
324324 func calcStakingParams (stake,amount,assetId) = if (stake)
325325 then {
326- let $t093469412 = calcStakingFuncAndAddres(stake, assetId)
327- let call = $t093469412._1
328- let stakingAddr = $t093469412._2
326+ let $t093629428 = calcStakingFuncAndAddres(stake, assetId)
327+ let call = $t093629428._1
328+ let stakingAddr = $t093629428._2
329329 $Tuple4(call, stakingAddr, nil, [AttachedPayment(assetId, amount)])
330330 }
331331 else {
332- let $t094989564 = calcStakingFuncAndAddres(stake, assetId)
333- let call = $t094989564._1
334- let stakingAddr = $t094989564._2
332+ let $t095149580 = calcStakingFuncAndAddres(stake, assetId)
333+ let call = $t095149580._1
334+ let stakingAddr = $t095149580._2
335335 $Tuple4(call, stakingAddr, [amount, toBase58String(assetId)], nil)
336336 }
337337
338338
339339 func calculateFeeDiscount (userAddr) = {
340340 let swopAmount = valueOrElse(getInteger(govAddress, (toString(userAddr) + kUserSwopInGov)), 0)
341341 let discountValues = split(getStringValue(oracle, kDiscountValues), ",")
342342 let discounts = split(getStringValue(oracle, kDiscounts), ",")
343343 if (if ((swopAmount >= parseIntValue(discountValues[0])))
344344 then (parseIntValue(discountValues[1]) > swopAmount)
345345 else false)
346346 then (feeScale6 - parseIntValue(discounts[0]))
347347 else if (if ((swopAmount >= parseIntValue(discountValues[1])))
348348 then (parseIntValue(discountValues[2]) > swopAmount)
349349 else false)
350350 then (feeScale6 - parseIntValue(discounts[1]))
351351 else if (if ((swopAmount >= parseIntValue(discountValues[2])))
352352 then (parseIntValue(discountValues[3]) > swopAmount)
353353 else false)
354354 then (feeScale6 - parseIntValue(discounts[2]))
355355 else if (if ((swopAmount >= parseIntValue(discountValues[3])))
356356 then (parseIntValue(discountValues[4]) > swopAmount)
357357 else false)
358358 then (feeScale6 - parseIntValue(discounts[3]))
359359 else if ((swopAmount >= parseIntValue(discountValues[4])))
360360 then (feeScale6 - parseIntValue(discounts[4]))
361361 else feeScale6
362362 }
363363
364364
365+func calcBalanceAndPmtRatio (ABalance,BBalance,minAmountToReceive,pmtAmount,pmtAssetId) = if ((balanceA > balanceB))
366+ then {
367+ let ratio = fraction(scale8, balanceA, balanceB)
368+ let pratio = if ((pmtAssetId == assetIdA))
369+ then fraction(scale8, minAmountToReceive, pmtAmount)
370+ else fraction(scale8, minAmountToReceive, pmtAmount)
371+ $Tuple2(ratio, pratio)
372+ }
373+ else {
374+ let ratio = fraction(scale8, balanceB, balanceA)
375+ let pratio = if ((pmtAssetId == assetIdA))
376+ then fraction(scale8, minAmountToReceive, pmtAmount)
377+ else fraction(scale8, minAmountToReceive, pmtAmount)
378+ $Tuple2(ratio, pratio)
379+ }
380+
381+
365382 @Callable(i)
366383 func init () = {
367- let $t01073610813 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
368- let pmtAmountA = $t01073610813._1
369- let pmtAssetIdA = $t01073610813._2
370- let $t01081810895 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
371- let pmtAmountB = $t01081810895._1
372- let pmtAssetIdB = $t01081810895._2
373- let $t01090010977 = getAssetInfo(pmtAssetIdA)
374- let pmtStrAssetIdA = $t01090010977._1
375- let pmtAssetNameA = $t01090010977._2
376- let pmtDecimalsA = $t01090010977._3
377- let $t01098211059 = getAssetInfo(pmtAssetIdB)
378- let pmtStrAssetIdB = $t01098211059._1
379- let pmtAssetNameB = $t01098211059._2
380- let pmtDecimalsB = $t01098211059._3
384+ let $t01149811575 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
385+ let pmtAmountA = $t01149811575._1
386+ let pmtAssetIdA = $t01149811575._2
387+ let $t01158011657 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
388+ let pmtAmountB = $t01158011657._1
389+ let pmtAssetIdB = $t01158011657._2
390+ let $t01166211739 = getAssetInfo(pmtAssetIdA)
391+ let pmtStrAssetIdA = $t01166211739._1
392+ let pmtAssetNameA = $t01166211739._2
393+ let pmtDecimalsA = $t01166211739._3
394+ let $t01174411821 = getAssetInfo(pmtAssetIdB)
395+ let pmtStrAssetIdB = $t01174411821._1
396+ let pmtAssetNameB = $t01174411821._2
397+ let pmtDecimalsB = $t01174411821._3
381398 if (isDefined(getBoolean(this, kActive)))
382399 then throwIsActive()
383400 else if ((pmtAssetIdA == pmtAssetIdB))
384401 then throw("Assets must be different")
385402 else {
386403 let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
387404 let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
388405 let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
389406 let shareInitialSupply = fraction(pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN), pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN), pow(10, 0, shareDecimals, 0, 0, DOWN))
390407 let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
391408 let shareIssueId = calculateAssetId(shareIssue)
392409 let invariantCalculated = invariantCalc(pmtAmountA, pmtAmountB)
393410 let stake1 = if (containsElement(stakingAssets, pmtStrAssetIdA))
394411 then invoke(this, "stakeUnstake", [true, pmtAmountA, pmtStrAssetIdA], nil)
395412 else 0
396413 if ((stake1 == stake1))
397414 then {
398415 let stake2 = if (containsElement(stakingAssets, pmtStrAssetIdB))
399416 then invoke(this, "stakeUnstake", [true, pmtAmountB, pmtStrAssetIdB], nil)
400417 else 0
401418 if ((stake2 == stake2))
402419 then [StringEntry(kVersion, version), BooleanEntry(kActive, true), StringEntry(kAssetIdA, pmtStrAssetIdA), StringEntry(kAssetIdB, pmtStrAssetIdB), IntegerEntry(kBalanceA, pmtAmountA), IntegerEntry(kBalanceB, pmtAmountB), IntegerEntry(kInvariant, invariantCalculated), IntegerEntry(kFee, getIntegerValue(oracle, "base_fee_flat")), shareIssue, StringEntry(kShareAssetId, toBase58String(shareIssueId)), IntegerEntry(kShareAssetSupply, shareInitialSupply), ScriptTransfer(i.caller, shareInitialSupply, shareIssueId)]
403420 else throw("Strict value is not equal to itself.")
404421 }
405422 else throw("Strict value is not equal to itself.")
406423 }
407424 }
408425
409426
410427
411428 @Callable(i)
412429 func replenishWithTwoTokens () = valueOrElse(isActive(), {
413430 let pmtAssetIdA = i.payments[0].assetId
414431 let pmtAssetIdB = i.payments[1].assetId
415432 let ratioShareTokensInA = fraction(scale8, i.payments[0].amount, balanceA)
416433 let ratioShareTokensInB = fraction(scale8, i.payments[1].amount, balanceB)
417- let $t01370713784 = getAssetInfo(pmtAssetIdA)
418- let pmtStrAssetIdA = $t01370713784._1
419- let pmtAssetNameA = $t01370713784._2
420- let pmtDecimalsA = $t01370713784._3
421- let $t01378913906 = getAssetInfo(pmtAssetIdB)
422- let pmtStrAssetIdB = $t01378913906._1
423- let pmtAssetNameB = $t01378913906._2
424- let pmtDecimalsB = $t01378913906._3
425- let $t01391114415 = if ((ratioShareTokensInB > ratioShareTokensInA))
434+ let $t01446914546 = getAssetInfo(pmtAssetIdA)
435+ let pmtStrAssetIdA = $t01446914546._1
436+ let pmtAssetNameA = $t01446914546._2
437+ let pmtDecimalsA = $t01446914546._3
438+ let $t01455114668 = getAssetInfo(pmtAssetIdB)
439+ let pmtStrAssetIdB = $t01455114668._1
440+ let pmtAssetNameB = $t01455114668._2
441+ let pmtDecimalsB = $t01455114668._3
442+ let $t01467315177 = if ((ratioShareTokensInB > ratioShareTokensInA))
426443 then {
427444 let pmt = fraction(balanceB, ratioShareTokensInA, scale8, CEILING)
428445 $Tuple5(i.payments[0].amount, pmt, (i.payments[1].amount - pmt), pmtAssetIdB, ratioShareTokensInA)
429446 }
430447 else {
431448 let pmt = fraction(balanceA, ratioShareTokensInB, scale8, CEILING)
432449 $Tuple5(pmt, i.payments[1].amount, (i.payments[0].amount - pmt), pmtAssetIdA, ratioShareTokensInB)
433450 }
434- let pmtAmountA = $t01391114415._1
435- let pmtAmountB = $t01391114415._2
436- let change = $t01391114415._3
437- let changeAssetId = $t01391114415._4
438- let shareTokenRatio = $t01391114415._5
451+ let pmtAmountA = $t01467315177._1
452+ let pmtAmountB = $t01467315177._2
453+ let change = $t01467315177._3
454+ let changeAssetId = $t01467315177._4
455+ let shareTokenRatio = $t01467315177._5
439456 let shareTokenToPayAmount = fraction(shareTokenRatio, shareAssetSupply, scale8)
440457 if ((size(i.payments) != 2))
441458 then throw("Two attached assets expected")
442459 else if (if ((pmtAssetIdA != assetIdA))
443460 then true
444461 else (pmtAssetIdB != assetIdB))
445462 then throwAssets()
446463 else if ((shareTokenToPayAmount == 0))
447464 then throw("Too small amount to replenish")
448465 else if ((0 > change))
449466 then throw("Change < 0")
450467 else if (!(hasEnoughBalance))
451468 then ([ScriptTransfer(i.caller, pmtAmountA, pmtAssetIdA), ScriptTransfer(i.caller, pmtAmountB, pmtAssetIdB)] ++ suspendSuspicious())
452469 else {
453470 let stake1 = if (containsElement(stakingAssets, pmtStrAssetIdA))
454471 then invoke(this, "stakeUnstake", [true, pmtAmountA, pmtStrAssetIdA], nil)
455472 else 0
456473 if ((stake1 == stake1))
457474 then {
458475 let stake2 = if (containsElement(stakingAssets, pmtStrAssetIdB))
459476 then invoke(this, "stakeUnstake", [true, pmtAmountB, pmtStrAssetIdB], nil)
460477 else 0
461478 if ((stake2 == stake2))
462479 then [IntegerEntry(kBalanceA, (balanceA + pmtAmountA)), IntegerEntry(kBalanceB, (balanceB + pmtAmountB)), IntegerEntry(kShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), IntegerEntry(kInvariant, invariantCalc((balanceA + pmtAmountA), (balanceB + pmtAmountB))), Reissue(shareAssetId, shareTokenToPayAmount, true), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId), ScriptTransfer(i.caller, change, changeAssetId)]
463480 else throw("Strict value is not equal to itself.")
464481 }
465482 else throw("Strict value is not equal to itself.")
466483 }
467484 })
468485
469486
470487
471488 @Callable(i)
472489 func replenishWithOneToken (virtualSwapTokenPay,virtualSwapTokenGet) = valueOrElse(isActive(), {
473- let $t01614816223 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
474- let pmtAmount = $t01614816223._1
475- let pmtAssetId = $t01614816223._2
476- let $t01622816301 = getAssetInfo(pmtAssetId)
477- let pmtStrAssetId = $t01622816301._1
478- let pmtAssetName = $t01622816301._2
479- let pmtDecimals = $t01622816301._3
490+ let $t01691016985 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
491+ let pmtAmount = $t01691016985._1
492+ let pmtAssetId = $t01691016985._2
493+ let $t01699017063 = getAssetInfo(pmtAssetId)
494+ let pmtStrAssetId = $t01699017063._1
495+ let pmtAssetName = $t01699017063._2
496+ let pmtDecimals = $t01699017063._3
480497 let pmtMinThreshold = 5000000
481498 let thresholdValueForMinTolerance = 50000000
482499 let tolerance = if ((thresholdValueForMinTolerance > pmtAmount))
483500 then 100000
484501 else 1
485502 let slippageValueMinForReplenish = (scale8 - ((scale8 * tolerance) / 10000000))
486503 let slippageValueMaxForReplenish = (scale8 + ((scale8 * tolerance) / 10000000))
487504 let slippageValueMinForSwap = (scale8 - ((scale8 * 1) / 10000000))
488505 if ((pmtMinThreshold > pmtAmount))
489506 then throw((((("Payment amount " + toString(pmtAmount)) + " does not exceed the minimum amount of ") + toString(pmtMinThreshold)) + " tokens"))
490507 else if ((size(i.payments) != 1))
491508 then throwOnePayment()
492509 else if (!(hasEnoughBalance))
493510 then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
494511 else if (if ((pmtAssetId != assetIdA))
495512 then (pmtAssetId != assetIdB)
496513 else false)
497514 then throwAssets()
498515 else {
499- let $t01727917921 = if ((pmtAssetId == assetIdA))
516+ let $t01804118683 = if ((pmtAssetId == assetIdA))
500517 then $Tuple6((pmtAmount - virtualSwapTokenPay), virtualSwapTokenGet, (balanceA + virtualSwapTokenPay), (balanceB - virtualSwapTokenGet), (balanceA + pmtAmount), balanceB)
501518 else $Tuple6(virtualSwapTokenGet, (pmtAmount - virtualSwapTokenPay), (balanceA - virtualSwapTokenGet), (balanceB + virtualSwapTokenPay), balanceA, (balanceB + pmtAmount))
502- let virtualReplenishA = $t01727917921._1
503- let virtualReplenishB = $t01727917921._2
504- let balanceAfterSwapA = $t01727917921._3
505- let balanceAfterSwapB = $t01727917921._4
506- let newBalanceA = $t01727917921._5
507- let newBalanceB = $t01727917921._6
519+ let virtualReplenishA = $t01804118683._1
520+ let virtualReplenishB = $t01804118683._2
521+ let balanceAfterSwapA = $t01804118683._3
522+ let balanceAfterSwapB = $t01804118683._4
523+ let newBalanceA = $t01804118683._5
524+ let newBalanceB = $t01804118683._6
508525 let invariantNew = invariantCalc(balanceAfterSwapA, balanceAfterSwapB)
509526 let ratioVirtualBalanceToVirtualReplenish = (fraction(scale16, balanceAfterSwapA, balanceAfterSwapB) / fraction(scale8, virtualReplenishA, virtualReplenishB))
510- let dAppThresholdAmount = fraction((newBalanceA + newBalanceB), dAppThreshold, (2 * dAppThresholdScale2))
511527 if (if ((slippageValueMinForSwap >= fraction(scale8, invariant, invariantNew)))
512528 then true
513529 else (invariant > invariantNew))
514530 then throw("Incorrect virtualSwapTokenPay or virtualSwapTokenGet value")
515531 else if (if ((slippageValueMinForReplenish > ratioVirtualBalanceToVirtualReplenish))
516532 then true
517533 else (ratioVirtualBalanceToVirtualReplenish > slippageValueMaxForReplenish))
518534 then throw("Swap with virtualSwapTokenPay and virtualSwapTokenGet is possible, but ratio after virtual swap is incorrect")
519- else if (if ((dAppThresholdAmount > newBalanceA))
520- then true
521- else (dAppThresholdAmount > newBalanceB))
522- then throwThreshold(dAppThresholdAmount, newBalanceA, newBalanceB)
523- else {
524- let ratioShareTokensInA = fraction(virtualReplenishA, scale8, balanceAfterSwapA)
525- let ratioShareTokensInB = fraction(virtualReplenishB, scale8, balanceAfterSwapB)
526- let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scale8)
527- let shareTokenToPayAmountAfterFee = fraction(shareTokenToPayAmount, (feeScale6 - (fee / 2)), feeScale6)
528- let shareTokenGovernanceReward = fraction(shareTokenToPayAmount, (feeGovernance / 2), feeScale6)
529- let governanceRewardTokenA = fraction(shareTokenGovernanceReward, balanceA, shareAssetSupply)
530- let governanceRewardTokenB = fraction(shareTokenGovernanceReward, balanceB, shareAssetSupply)
531- let $t01990820203 = if ((pmtStrAssetId == strAssetIdA))
532- then $Tuple3((pmtAmount - governanceRewardTokenA), governanceRewardTokenB, strAssetIdB)
533- else $Tuple3((pmtAmount - governanceRewardTokenB), governanceRewardTokenA, strAssetIdA)
534- let stakeAmount = $t01990820203._1
535- let unstakeAmount = $t01990820203._2
536- let unstakeAsset = $t01990820203._3
537- let stake1 = if (containsElement(stakingAssets, pmtStrAssetId))
538- then invoke(this, "stakeUnstake", [true, stakeAmount, pmtStrAssetId], nil)
539- else 0
540- if ((stake1 == stake1))
541- then {
542- let stake2 = if (containsElement(stakingAssets, unstakeAsset))
543- then invoke(this, "stakeUnstake", [false, unstakeAmount, unstakeAsset], nil)
544- else 0
545- if ((stake2 == stake2))
546- then [Reissue(shareAssetId, shareTokenToPayAmountAfterFee, true), ScriptTransfer(i.caller, shareTokenToPayAmountAfterFee, shareAssetId), ScriptTransfer(moneyBoxAddress, governanceRewardTokenA, assetIdA), ScriptTransfer(moneyBoxAddress, governanceRewardTokenB, assetIdB), IntegerEntry(kBalanceA, (newBalanceA - governanceRewardTokenA)), IntegerEntry(kBalanceB, (newBalanceB - governanceRewardTokenB)), IntegerEntry(kShareAssetSupply, (shareAssetSupply + shareTokenToPayAmountAfterFee)), IntegerEntry(kInvariant, invariantCalc((newBalanceA - governanceRewardTokenA), (newBalanceB - governanceRewardTokenB)))]
547- else throw("Strict value is not equal to itself.")
548- }
549- else throw("Strict value is not equal to itself.")
550- }
535+ else {
536+ let ratioShareTokensInA = fraction(virtualReplenishA, scale8, balanceAfterSwapA)
537+ let ratioShareTokensInB = fraction(virtualReplenishB, scale8, balanceAfterSwapB)
538+ let shareTokenToPayAmount = fraction(min([ratioShareTokensInA, ratioShareTokensInB]), shareAssetSupply, scale8)
539+ let shareTokenToPayAmountAfterFee = fraction(shareTokenToPayAmount, (feeScale6 - (fee / 2)), feeScale6)
540+ let shareTokenGovernanceReward = fraction(shareTokenToPayAmount, (feeGovernance / 2), feeScale6)
541+ let governanceRewardTokenA = fraction(shareTokenGovernanceReward, balanceA, shareAssetSupply)
542+ let governanceRewardTokenB = fraction(shareTokenGovernanceReward, balanceB, shareAssetSupply)
543+ let $t02039420689 = if ((pmtStrAssetId == strAssetIdA))
544+ then $Tuple3((pmtAmount - governanceRewardTokenA), governanceRewardTokenB, strAssetIdB)
545+ else $Tuple3((pmtAmount - governanceRewardTokenB), governanceRewardTokenA, strAssetIdA)
546+ let stakeAmount = $t02039420689._1
547+ let unstakeAmount = $t02039420689._2
548+ let unstakeAsset = $t02039420689._3
549+ let stake1 = if (containsElement(stakingAssets, pmtStrAssetId))
550+ then invoke(this, "stakeUnstake", [true, stakeAmount, pmtStrAssetId], nil)
551+ else 0
552+ if ((stake1 == stake1))
553+ then {
554+ let stake2 = if (containsElement(stakingAssets, unstakeAsset))
555+ then invoke(this, "stakeUnstake", [false, unstakeAmount, unstakeAsset], nil)
556+ else 0
557+ if ((stake2 == stake2))
558+ then [Reissue(shareAssetId, shareTokenToPayAmountAfterFee, true), ScriptTransfer(i.caller, shareTokenToPayAmountAfterFee, shareAssetId), ScriptTransfer(moneyBoxAddress, governanceRewardTokenA, assetIdA), ScriptTransfer(moneyBoxAddress, governanceRewardTokenB, assetIdB), IntegerEntry(kBalanceA, (newBalanceA - governanceRewardTokenA)), IntegerEntry(kBalanceB, (newBalanceB - governanceRewardTokenB)), IntegerEntry(kShareAssetSupply, (shareAssetSupply + shareTokenToPayAmountAfterFee)), IntegerEntry(kInvariant, invariantCalc((newBalanceA - governanceRewardTokenA), (newBalanceB - governanceRewardTokenB)))]
559+ else throw("Strict value is not equal to itself.")
560+ }
561+ else throw("Strict value is not equal to itself.")
562+ }
551563 }
552564 })
553565
554566
555567
556568 @Callable(i)
557569 func withdraw () = valueOrElse(isActive(), {
558- let $t02149021565 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
559- let pmtAmount = $t02149021565._1
560- let pmtAssetId = $t02149021565._2
570+ let $t02197622051 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
571+ let pmtAmount = $t02197622051._1
572+ let pmtAssetId = $t02197622051._2
561573 let amountToPayA = fraction(pmtAmount, balanceA, shareAssetSupply)
562574 let amountToPayB = fraction(pmtAmount, balanceB, shareAssetSupply)
563575 let invariantCalculated = invariantCalc((balanceA - amountToPayA), (balanceB - amountToPayB))
564576 if ((size(i.payments) != 1))
565577 then throwOnePayment()
566578 else if ((pmtAssetId != shareAssetId))
567579 then throw(("Incorrect asset attached. Expected: " + toBase58String(shareAssetId)))
568580 else if (!(hasEnoughBalance))
569581 then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
570582 else {
571583 let stake1 = if (containsElement(stakingAssets, strAssetIdA))
572584 then invoke(this, "stakeUnstake", [false, amountToPayA, strAssetIdA], nil)
573585 else 0
574586 if ((stake1 == stake1))
575587 then {
576588 let stake2 = if (containsElement(stakingAssets, strAssetIdB))
577589 then invoke(this, "stakeUnstake", [false, amountToPayB, strAssetIdB], nil)
578590 else 0
579591 if ((stake2 == stake2))
580592 then [IntegerEntry(kBalanceA, (balanceA - amountToPayA)), IntegerEntry(kBalanceB, (balanceB - amountToPayB)), IntegerEntry(kShareAssetSupply, (shareAssetSupply - pmtAmount)), IntegerEntry(kInvariant, invariantCalculated), Burn(shareAssetId, pmtAmount), ScriptTransfer(i.caller, amountToPayA, assetIdA), ScriptTransfer(i.caller, amountToPayB, assetIdB)]
581593 else throw("Strict value is not equal to itself.")
582594 }
583595 else throw("Strict value is not equal to itself.")
584596 }
585597 })
586598
587599
588600
589601 @Callable(i)
590602 func exchange (estimatedAmountToReceive,minAmountToReceive) = valueOrElse(isActive(), {
591- let $t02311623191 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
592- let pmtAmount = $t02311623191._1
593- let pmtAssetId = $t02311623191._2
603+ let $t02360223677 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
604+ let pmtAmount = $t02360223677._1
605+ let pmtAssetId = $t02360223677._2
594606 if ((0 >= estimatedAmountToReceive))
595607 then throw(("Estimated amount must be positive. Actual: " + toString(estimatedAmountToReceive)))
596608 else if ((minAmountToReceive > estimatedAmountToReceive))
597609 then throw("Minimal amount can't be greater than estimated.")
598610 else if ((size(i.payments) != 1))
599611 then throwOnePayment()
600612 else if (!(hasEnoughBalance))
601613 then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
602614 else if (if ((pmtAssetId != assetIdA))
603615 then (pmtAssetId != assetIdB)
604616 else false)
605617 then throwAssets()
606618 else if ((10000000 > pmtAmount))
607619 then throw("Only swap of 10.000000 or more tokens is allowed")
608- else if (if ((exchangeRatioLimitMin > fraction(scale8, minAmountToReceive, pmtAmount)))
609- then true
610- else (fraction(scale8, estimatedAmountToReceive, pmtAmount) > exchangeRatioLimitMax))
611- then throw("Incorrect args and pmt ratio")
612- else {
613- let sendAssetId = if ((pmtAssetId == assetIdA))
614- then assetIdB
615- else assetIdA
616- let amount = calculateSendAmount(estimatedAmountToReceive, minAmountToReceive, pmtAmount, pmtAssetId)
617- let feeDiscount = calculateFeeDiscount(i.originCaller)
618- let governanceReward = fraction(amount, fraction(feeGovernance, feeDiscount, feeScale6, CEILING), feeScale6)
619- let amountMinusFee = fraction(amount, (feeScale6 - fraction(fee, feeDiscount, feeScale6, CEILING)), feeScale6)
620- let $t02464424906 = if ((pmtAssetId == assetIdA))
621- then $Tuple2((balanceA + pmtAmount), ((balanceB - amountMinusFee) - governanceReward))
622- else $Tuple2(((balanceA - amountMinusFee) - governanceReward), (balanceB + pmtAmount))
623- let newBalanceA = $t02464424906._1
624- let newBalanceB = $t02464424906._2
625- let dAppThresholdAmount = fraction((newBalanceA + newBalanceB), dAppThreshold, (2 * dAppThresholdScale2))
626- if (if ((dAppThresholdAmount > newBalanceA))
627- then true
628- else (dAppThresholdAmount > newBalanceB))
629- then throwThreshold(dAppThresholdAmount, newBalanceA, newBalanceB)
630- else {
631- let $t02520525278 = getAssetInfo(pmtAssetId)
632- let pmtStrAssetId = $t02520525278._1
633- let pmtAssetName = $t02520525278._2
634- let pmtDecimals = $t02520525278._3
635- let $t02529125368 = getAssetInfo(sendAssetId)
636- let sendStrAssetId = $t02529125368._1
637- let sendAssetName = $t02529125368._2
638- let sendDecimals = $t02529125368._3
639- let stake1 = if (containsElement(stakingAssets, pmtStrAssetId))
640- then invoke(this, "stakeUnstake", [true, pmtAmount, pmtStrAssetId], nil)
641- else 0
642- if ((stake1 == stake1))
643- then {
644- let stake2 = if (containsElement(stakingAssets, sendStrAssetId))
645- then invoke(this, "stakeUnstake", [false, (amountMinusFee + governanceReward), sendStrAssetId], nil)
646- else 0
647- if ((stake2 == stake2))
648- then $Tuple2([IntegerEntry(kBalanceA, newBalanceA), IntegerEntry(kBalanceB, newBalanceB), IntegerEntry(kInvariant, invariantCalc(newBalanceA, newBalanceB)), ScriptTransfer(i.caller, amountMinusFee, sendAssetId), ScriptTransfer(moneyBoxAddress, governanceReward, sendAssetId)], $Tuple2(amountMinusFee, sendAssetId))
649- else throw("Strict value is not equal to itself.")
650- }
651- else throw("Strict value is not equal to itself.")
652- }
653- }
620+ else {
621+ let $t02436324479 = calcBalanceAndPmtRatio(balanceA, balanceB, minAmountToReceive, pmtAmount, pmtAssetId)
622+ let balanceRatio = $t02436324479._1
623+ let pmtRatio = $t02436324479._2
624+ if (((exchangeRatioLimit - fraction(exchangeRatioLimitCoef, balanceRatio, scale8)) > pmtRatio))
625+ then throw("Incorrect args and pmt ratio")
626+ else {
627+ let sendAssetId = if ((pmtAssetId == assetIdA))
628+ then assetIdB
629+ else assetIdA
630+ let amount = calculateSendAmount(estimatedAmountToReceive, minAmountToReceive, pmtAmount, pmtAssetId)
631+ let feeDiscount = calculateFeeDiscount(i.originCaller)
632+ let governanceReward = fraction(amount, fraction(feeGovernance, feeDiscount, feeScale6, CEILING), feeScale6)
633+ let amountMinusFee = fraction(amount, (feeScale6 - fraction(fee, feeDiscount, feeScale6, CEILING)), feeScale6)
634+ let $t02523425512 = if ((pmtAssetId == assetIdA))
635+ then $Tuple2((balanceA + pmtAmount), ((balanceB - amountMinusFee) - governanceReward))
636+ else $Tuple2(((balanceA - amountMinusFee) - governanceReward), (balanceB + pmtAmount))
637+ let newBalanceA = $t02523425512._1
638+ let newBalanceB = $t02523425512._2
639+ let dAppThresholdAmount = fraction((newBalanceA + newBalanceB), dAppThreshold, (2 * dAppThresholdScale2))
640+ if (if ((dAppThresholdAmount > newBalanceA))
641+ then true
642+ else (dAppThresholdAmount > newBalanceB))
643+ then throwThreshold(dAppThresholdAmount, newBalanceA, newBalanceB)
644+ else {
645+ let $t02583125904 = getAssetInfo(pmtAssetId)
646+ let pmtStrAssetId = $t02583125904._1
647+ let pmtAssetName = $t02583125904._2
648+ let pmtDecimals = $t02583125904._3
649+ let $t02592125998 = getAssetInfo(sendAssetId)
650+ let sendStrAssetId = $t02592125998._1
651+ let sendAssetName = $t02592125998._2
652+ let sendDecimals = $t02592125998._3
653+ let stake1 = if (containsElement(stakingAssets, pmtStrAssetId))
654+ then invoke(this, "stakeUnstake", [true, pmtAmount, pmtStrAssetId], nil)
655+ else 0
656+ if ((stake1 == stake1))
657+ then {
658+ let stake2 = if (containsElement(stakingAssets, sendStrAssetId))
659+ then invoke(this, "stakeUnstake", [false, (amountMinusFee + governanceReward), sendStrAssetId], nil)
660+ else 0
661+ if ((stake2 == stake2))
662+ then $Tuple2([IntegerEntry(kBalanceA, newBalanceA), IntegerEntry(kBalanceB, newBalanceB), IntegerEntry(kInvariant, invariantCalc(newBalanceA, newBalanceB)), ScriptTransfer(i.caller, amountMinusFee, sendAssetId), ScriptTransfer(moneyBoxAddress, governanceReward, sendAssetId)], $Tuple2(amountMinusFee, sendAssetId))
663+ else throw("Strict value is not equal to itself.")
664+ }
665+ else throw("Strict value is not equal to itself.")
666+ }
667+ }
668+ }
654669 })
655670
656671
657672
658673 @Callable(i)
659674 func shutdown () = valueOrElse(isAdminCall(i), if (!(active))
660675 then throw(("DApp is already suspended. Cause: " + valueOrElse(getString(this, kCause), "the cause wasn't specified")))
661676 else suspend("Paused by admin"))
662677
663678
664679
665680 @Callable(i)
666681 func activate () = valueOrElse(isAdminCall(i), if (active)
667682 then throwIsActive()
668683 else [BooleanEntry(kActive, true), DeleteEntry(kCause)])
669684
670685
671686
672687 @Callable(i)
673688 func takeIntoAccountExtraFunds () = valueOrElse(isActive(), {
674689 let amountEnrollA = (accountBalanceWithStakedA - balanceA)
675690 let amountEnrollB = (accountBalanceWithStakedB - balanceB)
676691 let invariantNew = invariantCalc((balanceA + amountEnrollA), (balanceB + amountEnrollB))
677692 if ((i.caller != moneyBoxAddress))
678693 then throw("Only the money box can call this function")
679694 else if (if ((0 > amountEnrollA))
680695 then true
681696 else (0 > amountEnrollB))
682697 then suspend("Enroll amount negative")
683698 else if (if ((amountEnrollA == 0))
684699 then (amountEnrollB == 0)
685700 else false)
686701 then throw("No money to take")
687702 else {
688703 let stake1 = if (if (containsElement(stakingAssets, strAssetIdA))
689704 then (amountEnrollA > 0)
690705 else false)
691706 then invoke(this, "stakeUnstake", [true, amountEnrollA, strAssetIdA], nil)
692707 else 0
693708 if ((stake1 == stake1))
694709 then {
695710 let stake2 = if (if (containsElement(stakingAssets, strAssetIdB))
696711 then (amountEnrollB > 0)
697712 else false)
698713 then invoke(this, "stakeUnstake", [true, amountEnrollB, strAssetIdB], nil)
699714 else 0
700715 if ((stake2 == stake2))
701716 then [IntegerEntry(kInvariant, invariantNew), IntegerEntry(kBalanceA, (balanceA + amountEnrollA)), IntegerEntry(kBalanceB, (balanceB + amountEnrollB))]
702717 else throw("Strict value is not equal to itself.")
703718 }
704719 else throw("Strict value is not equal to itself.")
705720 }
706721 })
707722
708723
709724
710725 @Callable(i)
711726 func stakeUnstake (stake,amount,assetIdString) = if ((i.caller != this))
712727 then throw("Only contract itself can invoke this function")
713728 else {
714- let $t02837228475 = calcStakingParams(stake, amount, fromBase58String(assetIdString))
715- let call = $t02837228475._1
716- let addr = $t02837228475._2
717- let params = $t02837228475._3
718- let payments = $t02837228475._4
729+ let $t02904129144 = calcStakingParams(stake, amount, fromBase58String(assetIdString))
730+ let call = $t02904129144._1
731+ let addr = $t02904129144._2
732+ let params = $t02904129144._3
733+ let payments = $t02904129144._4
719734 let inv = invoke(addr, call, params, payments)
720735 if ((inv == inv))
721736 then nil
722737 else throw("Strict value is not equal to itself.")
723738 }
724739
725740
726741
727742 @Callable(i)
728743 func toBigIntInvariant () = valueOrElse(isAdminCall(i), [IntegerEntry(kInvariant, invariantCalc(balanceA, balanceB))])
729744
730745
731746 @Verifier(tx)
732747 func verify () = {
733748 let multiSignedByAdmins = {
734749 let adminPubKey1Signed = if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
735750 then 1
736751 else 0
737752 let adminPubKey2Signed = if (sigVerify(tx.bodyBytes, tx.proofs[1], adminPubKey2))
738753 then 1
739754 else 0
740755 let adminPubKey3Signed = if (sigVerify(tx.bodyBytes, tx.proofs[2], adminPubKey3))
741756 then 1
742757 else 0
743758 (((adminPubKey1Signed + adminPubKey2Signed) + adminPubKey3Signed) >= 2)
744759 }
745760 match tx {
746761 case inv: InvokeScriptTransaction =>
747762 let callTakeIntoAccount = if ((inv.dApp == this))
748763 then (inv.function == "takeIntoAccountExtraFunds")
749764 else false
750765 let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
751766 then true
752767 else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey2))
753768 then true
754769 else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey3))
755770 then true
756771 else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKeyInvoke)
757772 if (if (callTakeIntoAccount)
758773 then signedByAdmin
759774 else false)
760775 then true
761776 else multiSignedByAdmins
762777 case _ =>
763778 multiSignedByAdmins
764779 }
765780 }
766781

github/deemru/w8io/026f985 
103.56 ms