diff options
Diffstat (limited to 'design-documents/047-stefan.rst')
-rw-r--r-- | design-documents/047-stefan.rst | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/design-documents/047-stefan.rst b/design-documents/047-stefan.rst new file mode 100644 index 00000000..4cef1865 --- /dev/null +++ b/design-documents/047-stefan.rst @@ -0,0 +1,172 @@ +DD 47: STEFAN +############# + +Summary +======= + +The Standardized Template for Effective-Fee Approximation Numbers (STEFAN) +is a feature to ensure customers see consistent fees for equivalent +purchases (largely) independent of the specific coins selected. It will also +make it easier for merchants to configure their systems to pay all reasonable +fees. + + +Motivation +========== + +Taler has a logarithmic fee structure for good reasons (to compete in +different market segments with reasonable profit margins). However, the +logarithmic fee structure inherently implies that the specific coin selection +made by the wallet can result in very different fees being applicable for the +same amount at the same merchant merely due to different coins being available +in the wallet. To minimize support costs, it is important that customers do +not need to be aware of the concept of coins and are instead shown consistent +fees for equivalent transactions. + + +Requirements +============ + + - keep the logarithmic nature of the fees (proportionally high fees + for tiny amounts, medium fees for medium amounts, low fees for large amounts) + - same purchase, same perceived price; prices are predictable for users + - enable merchants to easily cover all fees in most cases + + +Proposed Solution +================= + +The proposal is for the exchange to advertise three STEFAN-parameters that +encode a fee curve of the form ``stefan_abs + stefan_log * log P + +stefan_lin * P`` where P represents the gross price to be paid. +Here, the numerical value for P is to be computed by +dividing the actual gross price by the smallest denomination +offered by the exchange. + +.. note:: + + This calculation is already done using floating point (!) as we want the + STEFAN-curve to be smooth and not a step-function. This is also needed so + that we can invert the computation and calculate gross amounts from net + amounts and actually get a nice invertible computation where both + directions always match. Note that the computation itself is nevertheless + non-trivial involving Newton's method to solve ``f(x)=0`` using a + well-estimated starting point for the iteration to avoid divergence issues. + Finally, while we do the STEFAN-curve computations using doubles, we should + then convert the final amounts back into "human-friendly" numbers rounding + towards the nearest value that can be represented using the canonical + number of decimal places at the exchange. libtalerexchange (C) has a + reference implementation of the gross-net conversion functions (in both + directions) and of the final rounding logic. This exception to the general + rule of no floating-points for amounts is acceptable as it is not actually + done at the protocol level but only in internal computations of the wallet + and merchant backend as part of the STEFAN cost estimation logic, which by + definition is an estimate and does not need to be exact. (And even if + wallet and merchant backend were to (slightly) disagree about the + computations due to different floating point implementations, everything + would still be fine, and even a significant disagreement would not cause + anything but resurface the UI issue the STEFAN-curves addresses.) + +The fee curve will be the displayed fee, except in cases where the coin +selection is exceptionally bad (which should happen in substantially less than +1% of all cases). The fee curve will also be used as the maximum fee a +merchant will cover unless the merchant overrides the mechanism. + +In the most common case, where the STEFAN-curve fee is at or below what the +merchant covers, no fees are displayed, except in the exceptionally rare +case where the actual fees (due to unfortunate coin selection) are above +both the exchange's STEFAN-curve and the what the merchant covers. In this +last case the fees shown will be the actual fees minus what the merchant +covers and here the fees may vary even for equivalent transactions. + +In the uncommon case where a merchant does not cover any fees or only covers +parts of the fee according to the STEFAN-curve, the displayed fee will be the +value on the STEFAN-curve minus the amount covered by the merchant. If the +actual fees paid end up being below the approximation by the STEFAN-curve, the +delta is (by default) *hidden* from the balance of the user to simulate a +consistent fee. + +However, only the total available balance is marked down based on the +STEFAN-curve value. Thus, the wallet will contains coins with a potentially +higher balance value than what is shown to the user. This difference is +reconciled annually by adding a special transaction that increases the wallet +balance to eliminate the difference without any actual network interaction. +The entry in the transaction history that boosts the balance links to an +explanation. We may consider suggesting the user to donate the windfall. + +In developer mode, the user should probably be given the choice to see the +delta, to disable the feature, and/or to force the windfall transaction to +happen immediately. + + +Computing the curve +------------------- + +Typically, the ``stefan_abs`` value should represent a single wire transfer +fee. The ``stefan_log`` value should be computed to approximate the deposit +(and if applicable) refresh and withdraw fees for a coin, to be multiplied by +the number of coins. In a canonical setup, ``stefan_lin`` would be zero. +However, if an exchange is configured to use a linear fee structure, then +``stefan_lin`` would become applicable. + +The taler-wallet-cli should have an option to compute the STEFAN-values +given a denomination fee structure. This computation could probably be done +either analytically (if the fee structure is systematic) or by simulation. + +Modifications to the merchant +----------------------------- + +Instead of having (just) a "default fee", merchants should have an option to +use the STEFAN-curve when computing the fees they would be willing to cover. + +Modifications to the exchange +----------------------------- + +The STEFAN-curve can be configured using three simple configuration values +in the ``[exchange]`` section. The resulting values should be shared as +part of the ``/keys`` response, without digital signature. + +Modifications to the wallets +---------------------------- + +The STEFAN-curves will be useful as an easy approximate way to compare +exchange fee structures. However, wallets may not want to just trust an +exchange to honestly report STEFAN-curve values but could possibly use +a simulation to check that the given STEFAN-curve matches the actual fees. + +Wallets will need to keep the hidden STEFAN-balance and add the annual +internal reconcilliation transaction. + +Wallets will need to compute both the STEFAN-fee for display and still +do their own internal actual coin selection to minimize fees. + + + +Definition of Done +================== + + - exchange modified (DONE) + - merchant understands STEFAN curve in backend (DONE) + - merchant SPA has configuration option to enable use of STEFAN-curves + - wallet-core uses STEFAN-curves to compute display fees + - wallet-core supports annual reconcilliation transaction + - wallet GUIs use STEFAN-curves when comparing exchange fee structures + + +Alternatives +============ + +Refresh fees could additionally be waived if the refresh operation yields coins +of a lower denomination than the original coin. We should check if this allows +us to define tighter STEFAN-curves. + + +Drawbacks +========= + + + +Discussion / Q&A +================ + +(This should be filled in with results from discussions on mailing lists / personal communication.) |