047-stefan.rst (7588B)
1 DD 47: STEFAN 2 ############# 3 4 Summary 5 ======= 6 7 The Standardized Template for Effective-Fee Approximation Numbers (STEFAN) 8 is a feature to ensure customers see consistent fees for equivalent 9 purchases (largely) independent of the specific coins selected. It will also 10 make it easier for merchants to configure their systems to pay all reasonable 11 fees. 12 13 14 Motivation 15 ========== 16 17 Taler has a logarithmic fee structure for good reasons (to compete in 18 different market segments with reasonable profit margins). However, the 19 logarithmic fee structure inherently implies that the specific coin selection 20 made by the wallet can result in very different fees being applicable for the 21 same amount at the same merchant merely due to different coins being available 22 in the wallet. To minimize support costs, it is important that customers do 23 not need to be aware of the concept of coins and are instead shown consistent 24 fees for equivalent transactions. 25 26 27 Requirements 28 ============ 29 30 - keep the logarithmic nature of the fees (proportionally high fees 31 for tiny amounts, medium fees for medium amounts, low fees for large amounts) 32 - same purchase, same perceived price; prices are predictable for users 33 - enable merchants to easily cover all fees in most cases 34 35 36 Proposed Solution 37 ================= 38 39 The proposal is for the exchange to advertise three STEFAN-parameters that 40 encode a fee curve of the form ``stefan_abs + stefan_log * log P + 41 stefan_lin * P`` where P represents the gross price to be paid. 42 Here, the numerical value for P is to be computed by 43 dividing the actual gross price by the smallest denomination 44 offered by the exchange. 45 46 .. note:: 47 48 This calculation is already done using floating point (!) as we want the 49 STEFAN-curve to be smooth and not a step-function. This is also needed so 50 that we can invert the computation and calculate gross amounts from net 51 amounts and actually get a nice invertible computation where both 52 directions always match. Note that the computation itself is nevertheless 53 non-trivial involving Newton's method to solve ``f(x)=0`` using a 54 well-estimated starting point for the iteration to avoid divergence issues. 55 Finally, while we do the STEFAN-curve computations using doubles, we should 56 then convert the final amounts back into "human-friendly" numbers rounding 57 towards the nearest value that can be represented using the canonical 58 number of decimal places at the exchange. libtalerexchange (C) has a 59 reference implementation of the gross-net conversion functions (in both 60 directions) and of the final rounding logic. This exception to the general 61 rule of no floating-points for amounts is acceptable as it is not actually 62 done at the protocol level but only in internal computations of the wallet 63 and merchant backend as part of the STEFAN cost estimation logic, which by 64 definition is an estimate and does not need to be exact. (And even if 65 wallet and merchant backend were to (slightly) disagree about the 66 computations due to different floating point implementations, everything 67 would still be fine, and even a significant disagreement would not cause 68 anything but resurface the UI issue the STEFAN-curves addresses.) 69 70 The fee curve will be the displayed fee, except in cases where the coin 71 selection is exceptionally bad (which should happen in substantially less than 72 1% of all cases). The fee curve will also be used as the maximum fee a 73 merchant will cover unless the merchant overrides the mechanism. 74 75 In the most common case, where the STEFAN-curve fee is at or below what the 76 merchant covers, no fees are displayed, except in the exceptionally rare 77 case where the actual fees (due to unfortunate coin selection) are above 78 both the exchange's STEFAN-curve and the what the merchant covers. In this 79 last case the fees shown will be the actual fees minus what the merchant 80 covers and here the fees may vary even for equivalent transactions. 81 82 In the uncommon case where a merchant does not cover any fees or only covers 83 parts of the fee according to the STEFAN-curve, the displayed fee will be the 84 value on the STEFAN-curve minus the amount covered by the merchant. If the 85 actual fees paid end up being below the approximation by the STEFAN-curve, the 86 delta is (by default) *hidden* from the balance of the user to simulate a 87 consistent fee. 88 89 However, only the total available balance is marked down based on the 90 STEFAN-curve value. Thus, the wallet will contains coins with a potentially 91 higher balance value than what is shown to the user. This difference is 92 reconciled annually by adding a special transaction that increases the wallet 93 balance to eliminate the difference without any actual network interaction. 94 The entry in the transaction history that boosts the balance links to an 95 explanation. We may consider suggesting the user to donate the windfall. 96 97 In developer mode, the user should probably be given the choice to see the 98 delta, to disable the feature, and/or to force the windfall transaction to 99 happen immediately. 100 101 102 Computing the curve 103 ------------------- 104 105 Typically, the ``stefan_abs`` value should represent a single wire transfer 106 fee. The ``stefan_log`` value should be computed to approximate the deposit 107 (and if applicable) refresh and withdraw fees for a coin, to be multiplied by 108 the number of coins. In a canonical setup, ``stefan_lin`` would be zero. 109 However, if an exchange is configured to use a linear fee structure, then 110 ``stefan_lin`` would become applicable. 111 112 The taler-wallet-cli should have an option to compute the STEFAN-values 113 given a denomination fee structure. This computation could probably be done 114 either analytically (if the fee structure is systematic) or by simulation. 115 116 Modifications to the merchant 117 ----------------------------- 118 119 Instead of having (just) a "default fee", merchants should have an option to 120 use the STEFAN-curve when computing the fees they would be willing to cover. 121 122 Modifications to the exchange 123 ----------------------------- 124 125 The STEFAN-curve can be configured using three simple configuration values 126 in the ``[exchange]`` section. The resulting values should be shared as 127 part of the ``/keys`` response, without digital signature. 128 129 Modifications to the wallets 130 ---------------------------- 131 132 The STEFAN-curves will be useful as an easy approximate way to compare 133 exchange fee structures. However, wallets may not want to just trust an 134 exchange to honestly report STEFAN-curve values but could possibly use 135 a simulation to check that the given STEFAN-curve matches the actual fees. 136 137 Wallets will need to keep the hidden STEFAN-balance and add the annual 138 internal reconcilliation transaction. 139 140 Wallets will need to compute both the STEFAN-fee for display and still 141 do their own internal actual coin selection to minimize fees. 142 143 144 145 Definition of Done 146 ================== 147 148 - exchange modified (DONE) 149 - merchant understands STEFAN curve in backend (DONE) 150 - merchant SPA has configuration option to enable use of STEFAN-curves 151 - wallet-core uses STEFAN-curves to compute display fees 152 - wallet-core supports annual reconcilliation transaction 153 - wallet GUIs use STEFAN-curves when comparing exchange fee structures 154 155 156 Alternatives 157 ============ 158 159 Refresh fees could additionally be waived if the refresh operation yields coins 160 of a lower denomination than the original coin. We should check if this allows 161 us to define tighter STEFAN-curves. 162 163 164 Drawbacks 165 ========= 166 167 168 169 Discussion / Q&A 170 ================ 171 172 (This should be filled in with results from discussions on mailing lists / personal communication.)