tx · 2uP8kiTf22dqn4EmRGfPCLSSTSJ7EoxxYTv1L89WTAiV

3P56jNQzECXnrWpnbbSJKw7Eooo6fkUaMPp:  -0.00800000 Waves

2022.10.27 11:07 [3355941] smart account 3P56jNQzECXnrWpnbbSJKw7Eooo6fkUaMPp > SELF 0.00000000 Waves

{ "type": 13, "id": "2uP8kiTf22dqn4EmRGfPCLSSTSJ7EoxxYTv1L89WTAiV", "fee": 800000, "feeAssetId": null, "timestamp": 1666858040355, "version": 2, "chainId": 87, "sender": "3P56jNQzECXnrWpnbbSJKw7Eooo6fkUaMPp", "senderPublicKey": "94U1i8a6xwSbEsdvuEn8qhxovgKQFvb3a3cdJD2J27qH", "proofs": [ "", "", "59K328pDoDt3LFpiUDq2P1B8Z1PJ58nBP48Fr7qDhP6BaAcBmnnNSmHd3U5tCm8GE6unur6YJoqwCiz4ZGWA7LzH" ], "script": "base64:BgIKCAISBgoECAgIARsACWtBc3NldElkQQIKQV9hc3NldF9pZAAJa0Fzc2V0SWRCAgpCX2Fzc2V0X2lkAAlrQmFsYW5jZUECD0FfYXNzZXRfYmFsYW5jZQAJa0JhbGFuY2VCAg9CX2Fzc2V0X2JhbGFuY2UACmtEaXNjb3VudHMCCWRpc2NvdW50cwAPa0Rpc2NvdW50VmFsdWVzAg9kaXNjb3VudF92YWx1ZXMAD2tVc2VyR1N3b3BJbkdvdgINX0dTd29wX2Ftb3VudAAOa1VzZXJTd29wSW5Hb3YCDF9TV09QX2Ftb3VudAAEa0ZlZQIKY29tbWlzc2lvbgANa0FkbWluUHViS2V5MQILYWRtaW5fcHViXzEADWtBZG1pblB1YktleTICC2FkbWluX3B1Yl8yAA1rQWRtaW5QdWJLZXkzAgthZG1pbl9wdWJfMwASa0FkbWluSW52b2tlUHViS2V5AhBhZG1pbl9pbnZva2VfcHViAAtrR292QWRkcmVzcwISZ292ZXJuYW5jZV9hZGRyZXNzAAlmZWVTY2FsZTYAwIQ9AAZvcmFjbGUJAQdBZGRyZXNzAQEaAVeK/whomjW6QM1hdPISN96mN/D6OM7oHjgBE2dldEJhc2U1OEZyb21PcmFjbGUBA2tleQQHJG1hdGNoMAkAnQgCBQZvcmFjbGUFA2tleQMJAAECBQckbWF0Y2gwAgZTdHJpbmcEBnN0cmluZwUHJG1hdGNoMAkA2QQBBQZzdHJpbmcEB25vdGhpbmcFByRtYXRjaDAJAAIBCQCsAgIFA2tleQIIaXMgZW1wdHkADGFkbWluUHViS2V5MQkBE2dldEJhc2U1OEZyb21PcmFjbGUBBQ1rQWRtaW5QdWJLZXkxAAxhZG1pblB1YktleTIJARNnZXRCYXNlNThGcm9tT3JhY2xlAQUNa0FkbWluUHViS2V5MgAMYWRtaW5QdWJLZXkzCQETZ2V0QmFzZTU4RnJvbU9yYWNsZQEFDWtBZG1pblB1YktleTMAEWFkbWluSW52b2tlUHViS2V5CQETZ2V0QmFzZTU4RnJvbU9yYWNsZQEFEmtBZG1pbkludm9rZVB1YktleQAKZ292QWRkcmVzcwkBB0FkZHJlc3MBCQETZ2V0QmFzZTU4RnJvbU9yYWNsZQEFC2tHb3ZBZGRyZXNzARRjYWxjdWxhdGVGZWVEaXNjb3VudAEIdXNlckFkZHIECnN3b3BBbW91bnQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUKZ292QWRkcmVzcwkArAICBQh1c2VyQWRkcgUOa1VzZXJTd29wSW5Hb3YAAAQLZ1N3b3BBbW91bnQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUKZ292QWRkcmVzcwkArAICBQh1c2VyQWRkcgUPa1VzZXJHU3dvcEluR292BQpzd29wQW1vdW50BA5kaXNjb3VudFZhbHVlcwkAtQkCCQERQGV4dHJOYXRpdmUoMTA1MykCBQZvcmFjbGUFD2tEaXNjb3VudFZhbHVlcwIBLAQJZGlzY291bnRzCQC1CQIJARFAZXh0ck5hdGl2ZSgxMDUzKQIFBm9yYWNsZQUKa0Rpc2NvdW50cwIBLAMDCQBnAgULZ1N3b3BBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5kaXNjb3VudFZhbHVlcwAACQBmAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDmRpc2NvdW50VmFsdWVzAAEFC2dTd29wQW1vdW50BwkAZQIFCWZlZVNjYWxlNgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCWRpc2NvdW50cwAAAwMJAGcCBQtnU3dvcEFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDmRpc2NvdW50VmFsdWVzAAEJAGYCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUOZGlzY291bnRWYWx1ZXMAAgULZ1N3b3BBbW91bnQHCQBlAgUJZmVlU2NhbGU2CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUJZGlzY291bnRzAAEDAwkAZwIFC2dTd29wQW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUOZGlzY291bnRWYWx1ZXMAAgkAZgIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5kaXNjb3VudFZhbHVlcwADBQtnU3dvcEFtb3VudAcJAGUCBQlmZWVTY2FsZTYJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQlkaXNjb3VudHMAAgMDCQBnAgULZ1N3b3BBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5kaXNjb3VudFZhbHVlcwADCQBmAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDmRpc2NvdW50VmFsdWVzAAQFC2dTd29wQW1vdW50BwkAZQIFCWZlZVNjYWxlNgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCWRpc2NvdW50cwADAwkAZwIFC2dTd29wQW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUOZGlzY291bnRWYWx1ZXMABAkAZQIFCWZlZVNjYWxlNgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCWRpc2NvdW50cwAEBQlmZWVTY2FsZTYBD2dldFBvb2xCYWxhbmNlcwEEcG9vbAQIYmFsYW5jZUEJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHBvb2wFCWtCYWxhbmNlQQQIYmFsYW5jZUIJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHBvb2wFCWtCYWxhbmNlQgkAlAoCBQhiYWxhbmNlQQUIYmFsYW5jZUIBDWdldFBvb2xBc3NldHMBBHBvb2wEC3N0ckFzc2V0SWRBCQERQGV4dHJOYXRpdmUoMTA1MykCBQRwb29sBQlrQXNzZXRJZEEEC3N0ckFzc2V0SWRCCQERQGV4dHJOYXRpdmUoMTA1MykCBQRwb29sBQlrQXNzZXRJZEIECGFzc2V0SWRBAwkAAAIFC3N0ckFzc2V0SWRBAgVXQVZFUwUEdW5pdAkA2QQBBQtzdHJBc3NldElkQQQIYXNzZXRJZEIDCQAAAgULc3RyQXNzZXRJZEICBVdBVkVTBQR1bml0CQDZBAEFC3N0ckFzc2V0SWRCCQCWCgQFC3N0ckFzc2V0SWRBBQtzdHJBc3NldElkQgUIYXNzZXRJZEEFCGFzc2V0SWRCAQxnZXRGZWVQYXJhbXMCBHBvb2wGY2FsbGVyBAtmZWVEaXNjb3VudAkBFGNhbGN1bGF0ZUZlZURpc2NvdW50AQUGY2FsbGVyBANmZWUJAG4ECQERQGV4dHJOYXRpdmUoMTA1MCkCBQRwb29sBQRrRmVlBQtmZWVEaXNjb3VudAUJZmVlU2NhbGU2BQdDRUlMSU5HBAZnb3ZGZWUJAG4ECQBrAwUDZmVlACgAZAULZmVlRGlzY291bnQFCWZlZVNjYWxlNgUHQ0VJTElORwkAlAoCBQNmZWUFBmdvdkZlZQENY2FsY3VsYXRlRmVlcwUJcG10QW1vdW50CXRva2VuRnJvbQd0b2tlblRvA2ZlZQ1mZWVHb3Zlcm5hbmNlBBBhbW91bnRXaXRob3V0RmVlCQBrAwUHdG9rZW5UbwUJcG10QW1vdW50CQBkAgUJcG10QW1vdW50BQl0b2tlbkZyb20EDWFtb3VudFdpdGhGZWUJAGsDBRBhbW91bnRXaXRob3V0RmVlCQBlAgUJZmVlU2NhbGU2BQNmZWUFCWZlZVNjYWxlNgkAlAoCBRBhbW91bnRXaXRob3V0RmVlBQ1hbW91bnRXaXRoRmVlAQFpARFjYWxjR2V0QW1vdW50Q1BNTQQIZEFwcEFkZHIIdXNlckFkZHIKcG10QXNzZXRJZAlwbXRBbW91bnQEBHBvb2wJAQdBZGRyZXNzAQkA2QQBBQhkQXBwQWRkcgQLJHQwMzYxNzM2NjMJAQ1nZXRQb29sQXNzZXRzAQUEcG9vbAQIYXNzZXRJZEEIBQskdDAzNjE3MzY2MwJfMQQIYXNzZXRJZEIIBQskdDAzNjE3MzY2MwJfMgQLJHQwMzY2NzM3MTUJAQ9nZXRQb29sQmFsYW5jZXMBBQRwb29sBAhiYWxhbmNlQQgFCyR0MDM2NjczNzE1Al8xBAhiYWxhbmNlQggFCyR0MDM2NjczNzE1Al8yAwMJAAACBQhiYWxhbmNlQQAABgkAAAIFCGJhbGFuY2VCAAAJAAIBAiBDYW4ndCBleGNoYW5nZSB3aXRoIHplcm8gYmFsYW5jZQMJAQEhAQkBD2NvbnRhaW5zRWxlbWVudAIJAMwIAgUIYXNzZXRJZEEJAMwIAgUIYXNzZXRJZEIFA25pbAUKcG10QXNzZXRJZAkAAgEJAKwCAgkArAICCQCsAgICJEluY29ycmVjdCBhc3NldCBhdHRhY2hlZC4gRXhwZWN0ZWQ6IAUIYXNzZXRJZEECBCBvciAFCGFzc2V0SWRCBAskdDAzOTc1NDAyMwkBDGdldEZlZVBhcmFtcwIFBHBvb2wFCHVzZXJBZGRyBANmZWUIBQskdDAzOTc1NDAyMwJfMQQGZ292RmVlCAULJHQwMzk3NTQwMjMCXzIECyR0MDQwMzA0MjUzAwkAAAIFCnBtdEFzc2V0SWQFCGFzc2V0SWRBCQENY2FsY3VsYXRlRmVlcwUFCXBtdEFtb3VudAUIYmFsYW5jZUEFCGJhbGFuY2VCBQNmZWUFBmdvdkZlZQkBDWNhbGN1bGF0ZUZlZXMFBQlwbXRBbW91bnQFCGJhbGFuY2VCBQhiYWxhbmNlQQUDZmVlBQZnb3ZGZWUEEGFtb3VudFdpdGhvdXRGZWUIBQskdDA0MDMwNDI1MwJfMQQNYW1vdW50V2l0aEZlZQgFCyR0MDQwMzA0MjUzAl8yCQCUCgIFA25pbAUNYW1vdW50V2l0aEZlZQECdHgBBnZlcmlmeQAEEmFkbWluUHViS2V5MVNpZ25lZAMJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAFDGFkbWluUHViS2V5MQABAAAEEmFkbWluUHViS2V5MlNpZ25lZAMJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAEFDGFkbWluUHViS2V5MgABAAAEEmFkbWluUHViS2V5M1NpZ25lZAMJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAIFDGFkbWluUHViS2V5MwABAAAJAGcCCQBkAgkAZAIFEmFkbWluUHViS2V5MVNpZ25lZAUSYWRtaW5QdWJLZXkyU2lnbmVkBRJhZG1pblB1YktleTNTaWduZWQAASRIGOI=", "height": 3355941, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 8npbGPFUmCGzE5xTCGGrbZRJH9wH67rRTDojpFdeRmE1 Next: none Diff:
OldNewDifferences
5252 let govAddress = Address(getBase58FromOracle(kGovAddress))
5353
5454 func calculateFeeDiscount (userAddr) = {
55- let swopAmount = valueOrElse(getInteger(govAddress, (toString(userAddr) + kUserSwopInGov)), 0)
56- let gSwopAmount = valueOrElse(getInteger(govAddress, (toString(userAddr) + kUserGSwopInGov)), swopAmount)
55+ let swopAmount = valueOrElse(getInteger(govAddress, (userAddr + kUserSwopInGov)), 0)
56+ let gSwopAmount = valueOrElse(getInteger(govAddress, (userAddr + kUserGSwopInGov)), swopAmount)
5757 let discountValues = split(getStringValue(oracle, kDiscountValues), ",")
5858 let discounts = split(getStringValue(oracle, kDiscounts), ",")
5959 if (if ((gSwopAmount >= parseIntValue(discountValues[0])))
116116 @Callable(i)
117117 func calcGetAmountCPMM (dAppAddr,userAddr,pmtAssetId,pmtAmount) = {
118118 let pool = Address(fromBase58String(dAppAddr))
119- let $t036423688 = getPoolAssets(pool)
120- let assetIdA = $t036423688._1
121- let assetIdB = $t036423688._2
122- let $t036923740 = getPoolBalances(pool)
123- let balanceA = $t036923740._1
124- let balanceB = $t036923740._2
119+ let $t036173663 = getPoolAssets(pool)
120+ let assetIdA = $t036173663._1
121+ let assetIdB = $t036173663._2
122+ let $t036673715 = getPoolBalances(pool)
123+ let balanceA = $t036673715._1
124+ let balanceB = $t036673715._2
125125 if (if ((balanceA == 0))
126126 then true
127127 else (balanceB == 0))
129129 else if (!(containsElement([assetIdA, assetIdB], pmtAssetId)))
130130 then throw(((("Incorrect asset attached. Expected: " + assetIdA) + " or ") + assetIdB))
131131 else {
132- let $t040004058 = getFeeParams(i.caller, i.originCaller)
133- let fee = $t040004058._1
134- let govFee = $t040004058._2
135- let $t040654288 = if ((pmtAssetId == assetIdA))
132+ let $t039754023 = getFeeParams(pool, userAddr)
133+ let fee = $t039754023._1
134+ let govFee = $t039754023._2
135+ let $t040304253 = if ((pmtAssetId == assetIdA))
136136 then calculateFees(pmtAmount, balanceA, balanceB, fee, govFee)
137137 else calculateFees(pmtAmount, balanceB, balanceA, fee, govFee)
138- let amountWithoutFee = $t040654288._1
139- let amountWithFee = $t040654288._2
138+ let amountWithoutFee = $t040304253._1
139+ let amountWithFee = $t040304253._2
140140 $Tuple2(nil, amountWithFee)
141141 }
142142 }
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let kAssetIdA = "A_asset_id"
55
66 let kAssetIdB = "B_asset_id"
77
88 let kBalanceA = "A_asset_balance"
99
1010 let kBalanceB = "B_asset_balance"
1111
1212 let kDiscounts = "discounts"
1313
1414 let kDiscountValues = "discount_values"
1515
1616 let kUserGSwopInGov = "_GSwop_amount"
1717
1818 let kUserSwopInGov = "_SWOP_amount"
1919
2020 let kFee = "commission"
2121
2222 let kAdminPubKey1 = "admin_pub_1"
2323
2424 let kAdminPubKey2 = "admin_pub_2"
2525
2626 let kAdminPubKey3 = "admin_pub_3"
2727
2828 let kAdminInvokePubKey = "admin_invoke_pub"
2929
3030 let kGovAddress = "governance_address"
3131
3232 let feeScale6 = 1000000
3333
3434 let oracle = Address(base58'3PEbqViERCoKnmcSULh6n2aiMvUdSQdCsom')
3535
3636 func getBase58FromOracle (key) = match getString(oracle, key) {
3737 case string: String =>
3838 fromBase58String(string)
3939 case nothing =>
4040 throw((key + "is empty"))
4141 }
4242
4343
4444 let adminPubKey1 = getBase58FromOracle(kAdminPubKey1)
4545
4646 let adminPubKey2 = getBase58FromOracle(kAdminPubKey2)
4747
4848 let adminPubKey3 = getBase58FromOracle(kAdminPubKey3)
4949
5050 let adminInvokePubKey = getBase58FromOracle(kAdminInvokePubKey)
5151
5252 let govAddress = Address(getBase58FromOracle(kGovAddress))
5353
5454 func calculateFeeDiscount (userAddr) = {
55- let swopAmount = valueOrElse(getInteger(govAddress, (toString(userAddr) + kUserSwopInGov)), 0)
56- let gSwopAmount = valueOrElse(getInteger(govAddress, (toString(userAddr) + kUserGSwopInGov)), swopAmount)
55+ let swopAmount = valueOrElse(getInteger(govAddress, (userAddr + kUserSwopInGov)), 0)
56+ let gSwopAmount = valueOrElse(getInteger(govAddress, (userAddr + kUserGSwopInGov)), swopAmount)
5757 let discountValues = split(getStringValue(oracle, kDiscountValues), ",")
5858 let discounts = split(getStringValue(oracle, kDiscounts), ",")
5959 if (if ((gSwopAmount >= parseIntValue(discountValues[0])))
6060 then (parseIntValue(discountValues[1]) > gSwopAmount)
6161 else false)
6262 then (feeScale6 - parseIntValue(discounts[0]))
6363 else if (if ((gSwopAmount >= parseIntValue(discountValues[1])))
6464 then (parseIntValue(discountValues[2]) > gSwopAmount)
6565 else false)
6666 then (feeScale6 - parseIntValue(discounts[1]))
6767 else if (if ((gSwopAmount >= parseIntValue(discountValues[2])))
6868 then (parseIntValue(discountValues[3]) > gSwopAmount)
6969 else false)
7070 then (feeScale6 - parseIntValue(discounts[2]))
7171 else if (if ((gSwopAmount >= parseIntValue(discountValues[3])))
7272 then (parseIntValue(discountValues[4]) > gSwopAmount)
7373 else false)
7474 then (feeScale6 - parseIntValue(discounts[3]))
7575 else if ((gSwopAmount >= parseIntValue(discountValues[4])))
7676 then (feeScale6 - parseIntValue(discounts[4]))
7777 else feeScale6
7878 }
7979
8080
8181 func getPoolBalances (pool) = {
8282 let balanceA = getIntegerValue(pool, kBalanceA)
8383 let balanceB = getIntegerValue(pool, kBalanceB)
8484 $Tuple2(balanceA, balanceB)
8585 }
8686
8787
8888 func getPoolAssets (pool) = {
8989 let strAssetIdA = getStringValue(pool, kAssetIdA)
9090 let strAssetIdB = getStringValue(pool, kAssetIdB)
9191 let assetIdA = if ((strAssetIdA == "WAVES"))
9292 then unit
9393 else fromBase58String(strAssetIdA)
9494 let assetIdB = if ((strAssetIdB == "WAVES"))
9595 then unit
9696 else fromBase58String(strAssetIdB)
9797 $Tuple4(strAssetIdA, strAssetIdB, assetIdA, assetIdB)
9898 }
9999
100100
101101 func getFeeParams (pool,caller) = {
102102 let feeDiscount = calculateFeeDiscount(caller)
103103 let fee = fraction(getIntegerValue(pool, kFee), feeDiscount, feeScale6, CEILING)
104104 let govFee = fraction(fraction(fee, 40, 100), feeDiscount, feeScale6, CEILING)
105105 $Tuple2(fee, govFee)
106106 }
107107
108108
109109 func calculateFees (pmtAmount,tokenFrom,tokenTo,fee,feeGovernance) = {
110110 let amountWithoutFee = fraction(tokenTo, pmtAmount, (pmtAmount + tokenFrom))
111111 let amountWithFee = fraction(amountWithoutFee, (feeScale6 - fee), feeScale6)
112112 $Tuple2(amountWithoutFee, amountWithFee)
113113 }
114114
115115
116116 @Callable(i)
117117 func calcGetAmountCPMM (dAppAddr,userAddr,pmtAssetId,pmtAmount) = {
118118 let pool = Address(fromBase58String(dAppAddr))
119- let $t036423688 = getPoolAssets(pool)
120- let assetIdA = $t036423688._1
121- let assetIdB = $t036423688._2
122- let $t036923740 = getPoolBalances(pool)
123- let balanceA = $t036923740._1
124- let balanceB = $t036923740._2
119+ let $t036173663 = getPoolAssets(pool)
120+ let assetIdA = $t036173663._1
121+ let assetIdB = $t036173663._2
122+ let $t036673715 = getPoolBalances(pool)
123+ let balanceA = $t036673715._1
124+ let balanceB = $t036673715._2
125125 if (if ((balanceA == 0))
126126 then true
127127 else (balanceB == 0))
128128 then throw("Can't exchange with zero balance")
129129 else if (!(containsElement([assetIdA, assetIdB], pmtAssetId)))
130130 then throw(((("Incorrect asset attached. Expected: " + assetIdA) + " or ") + assetIdB))
131131 else {
132- let $t040004058 = getFeeParams(i.caller, i.originCaller)
133- let fee = $t040004058._1
134- let govFee = $t040004058._2
135- let $t040654288 = if ((pmtAssetId == assetIdA))
132+ let $t039754023 = getFeeParams(pool, userAddr)
133+ let fee = $t039754023._1
134+ let govFee = $t039754023._2
135+ let $t040304253 = if ((pmtAssetId == assetIdA))
136136 then calculateFees(pmtAmount, balanceA, balanceB, fee, govFee)
137137 else calculateFees(pmtAmount, balanceB, balanceA, fee, govFee)
138- let amountWithoutFee = $t040654288._1
139- let amountWithFee = $t040654288._2
138+ let amountWithoutFee = $t040304253._1
139+ let amountWithFee = $t040304253._2
140140 $Tuple2(nil, amountWithFee)
141141 }
142142 }
143143
144144
145145 @Verifier(tx)
146146 func verify () = {
147147 let adminPubKey1Signed = if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
148148 then 1
149149 else 0
150150 let adminPubKey2Signed = if (sigVerify(tx.bodyBytes, tx.proofs[1], adminPubKey2))
151151 then 1
152152 else 0
153153 let adminPubKey3Signed = if (sigVerify(tx.bodyBytes, tx.proofs[2], adminPubKey3))
154154 then 1
155155 else 0
156156 (((adminPubKey1Signed + adminPubKey2Signed) + adminPubKey3Signed) >= 1)
157157 }
158158

github/deemru/w8io/873ac7e 
47.49 ms