-
Notifications
You must be signed in to change notification settings - Fork 191
/
manualPriceAuthority.js
89 lines (79 loc) · 2.39 KB
/
manualPriceAuthority.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import { AmountMath, makeIssuerKit, AssetKind } from '@agoric/ertp';
import { E } from '@endo/eventual-send';
import { Far } from '@endo/marshal';
import { makeNotifierKit } from '@agoric/notifier';
import {
makeOnewayPriceAuthorityKit,
floorMultiplyBy,
floorDivideBy,
} from '../src/contractSupport/index.js';
/**
*
* @param {object} options
* @param {Brand} options.actualBrandIn
* @param {Brand} options.actualBrandOut
* @param {Ratio} options.initialPrice
* @param {TimerService} options.timer
* @param {IssuerKit<'set'>} [options.quoteIssuerKit]
* @returns {PriceAuthority & { setPrice: (Ratio) => void }}
*/
export function makeManualPriceAuthority(options) {
const {
actualBrandIn,
actualBrandOut,
initialPrice, // brandOut / brandIn
timer,
quoteIssuerKit = makeIssuerKit('quote', AssetKind.SET),
} = options;
const { brand, issuer: quoteIssuer, mint: quoteMint } = quoteIssuerKit;
/** @type {Ratio} */
let currentPrice = initialPrice;
const { notifier, updater } = makeNotifierKit();
updater.updateState(currentPrice);
/** @param {PriceQuoteValue} quote */
const authenticateQuote = quote => {
const quoteAmount = AmountMath.make(brand, harden(quote));
const quotePayment = quoteMint.mintPayment(quoteAmount);
return harden({ quoteAmount, quotePayment });
};
const calcAmountOut = amountIn => {
AmountMath.coerce(actualBrandIn, amountIn);
return floorMultiplyBy(amountIn, currentPrice);
};
const calcAmountIn = amountOut => {
return floorDivideBy(amountOut, currentPrice);
};
function createQuote(priceQuery) {
const quote = priceQuery(calcAmountOut, calcAmountIn);
if (!quote) {
return undefined;
}
const { amountIn, amountOut } = quote;
return E(timer)
.getCurrentTimestamp()
.then(now =>
authenticateQuote([{ amountIn, amountOut, timer, timestamp: now }]),
);
}
/* --* @type {ERef<Notifier<Timestamp>>} */
const priceAuthorityOptions = harden({
timer,
createQuote,
actualBrandIn,
actualBrandOut,
quoteIssuer,
notifier,
});
const {
priceAuthority,
adminFacet: { fireTriggers },
} = makeOnewayPriceAuthorityKit(priceAuthorityOptions);
return Far('ManualPriceAuthority', {
setPrice: newPrice => {
currentPrice = newPrice;
updater.updateState(currentPrice);
fireTriggers(createQuote);
},
...priceAuthority,
});
}