Sekizinci Ders - Agoric Önceden Oluşturulmuş Sözleşmeleri & Fiyat Otoritesi
İçerik Tablosu
- Önceden oluşturulmuş sözleşmeler
- Finanse Edilmiş Call Spread (Opsiyonlar Stratejisi)
- Basit Borsa
- Fiyat Otoritesi
- Fiyat Teklifi
- Fiyat Teklifi Bildiricisi
- Anlık Fiyat Teklifleri
- VerilenTeklif
- ArananTeklif
- Söz Verilen Fiyat Teklifi
- NeZamanTeklif
- DeğiştirilebilirNeZamanTeklif
- Manuel Fiyat Otoritesi
Agoric Önceden Oluşturulmuş Sözleşmeleri
Agoric, geliştiricilerin uygulamalarını oluştururken yardımcı olmak için oluşturulan Agoric Önceden Oluşturulmuş Sözleşmeleri adlı bir liste sunar. Bu sözleşmeler, Agoric'in yüksek düzeyli (high-order)
özelliklerinden yararlanarak bir ana sözleşme aracılığıyla örneklenmelidir.
Daha fazla bilgi için Dördüncü Ders'i incelemenizi öneririz.
İki farklı paketten seçtiğimiz iki sözleşme, bu sözleşmelerin işlevselliğini ve nasıl kullanılacağını göstermektedir.
Finanse Edilmiş Call Spread
DeFi paketi
nden finanse edilmiş call spread
sözleşmesi, tamamen teminatlandırılmış bir call spread'i uygular.
Bir call spread
'inde yatırımcı, daha düşük bir kullanım fiyatı
na sahip bir call opsiyonu
satın alır (bu "uzun call" olarak adlandırılır) ve daha yüksek bir kullanım fiyatına
sahip başka bir call opsiyonu satar (bu "kısa call" olarak adlandırılır). Kullanım fiyatlarındaki fark, bir spread
oluşturur ve stratejinin amacı, iki kullanım fiyatı arasındaki farktan kar etmektir. Uzun call, sınırlı bir yukarı yönlü potansiyel sağlar, kısa call ise gelir üretir ve uzun call'ın maliyetini karşılamaya yardımcı olur. Bir call spread'de satılan ve alınan iki opsiyonun aynı vade tarihine
sahip olması gerekir.
Bir call opsiyonu
, sahibine belirli bir fiyat (kullanım fiyatı) karşılığında belirli bir zaman dilimi içerisinde bir varlığı (örneğin bir hisse senedi, emtia veya para birimi) satın alma hakkı veren, ancak zorunluluğu olmayan bir finansal sözleşmedir. Call opsiyonları, yatırım ve spekülasyon formu olarak, aynı zamanda hedging (riskten korunma) amacıyla da kullanılır. Eğer dayanak varlığın fiyatı, kullanım fiyatının üzerine çıkarsa, call opsiyonunun sahibi opsiyonu kullanmayı seçebilir ve varlığı daha düşük kullanım fiyatından satın alabilir, bu da bir kar anlamına gelir. Eğer fiyat, kullanım fiyatının üzerine çıkmazsa, opsiyon değersiz hale gelir ve opsiyon için ödenen prim kaybedilir.
Daha fazla bilgi için, aşağıdakileri okumanızı öneririz:
Ana sözleşmenizde finanse edilmiş call spread sözleşmesi kurulumu
na erişiminiz olduğunu varsayarsak, startInstance
fonksiyonunu çağırmak için gereken argümanlar issuerKeywordRecord
ve terms
dir.
const { creatorInvitation } = await E(zoe).startInstance(
installation,
issuerKeywordRecord,
terms
);
IssuerKeywordRecord, Dayanak Varlık, Teminat ve Kullanım Fiyatı varlıkları
nın Düzenleyicisi
ni belirtir.
Dayanak Varlık ve Teminat, aynı Düzenleyiciye sahip olabilir ve Kullanım Fiyatı farklı bir Düzenleyiciye sahip olabilir, veya uygulamanızın bağlamına bağlı olarak üç farklı Düzenleyiciye sahip olabilirsiniz.
Dayanak varlık/kullanım fiyatı çiftinin fiyat otoritesi
nin Düzenleyicisi de issuerKeywordRecord'a dahildir.
const issuerKeywordRecord = harden({
Underlying: simoleanIssuer,
Collateral: bucksIssuer,
Strike: moolaIssuer,
Quote: await E(priceAuthority).getQuoteIssuer(
brands.get("simoleans"),
brands.get("moola")
),
});
issuerKeywordRecord
, simoleanIssuer
olarak belirlenen Underlying
, bucksIssuer
olarak belirlenen Collateral
, moolaIssuer
olarak belirlenen Strike
ve priceAuthority
'den alınan Quote
olmak üzere belirli Issuer
'ları belirler.
terms
tarafına gelince, bunlar aşağıdakileri içerir:
expiration
: Opsiyonun kullanılabilir olduğu süreyi belirler.priceAuthority
: Süre sonunda, temel varlığın değerini strike para biriminde veren bir Fiyat Teklifi çıkarır.underlyingAmount
: Takip edilen varlığın fiyatı.strikePrice1
vestrikePrice2
: Sırasıyla kısa ve uzun olarak tanımlanan değerler.settlementAmount
: Opsiyonların sahipleri arasında bölünen ve fon sağlayıcı tarafından yatırılan teminat miktarı.timer
:priceAuthority
tarafından tanınan zamanlayıcı.
const terms = harden({
expiration: 2n,
underlyingAmount: simoleans(2n),
priceAuthority,
strikePrice1: moola(60n),
strikePrice2: moola(100n),
settlementAmount: bucks(300n),
timer: manualTimer,
});
Ev sahibi sözleşme, LongOption
ve ShortOption
adında iki opsiyonu geri almak için fundedCallSpread'e bir teklif
yapar.
Teklifi oluşturmak için, startInstance() çağrıldığında geri dönen creatorInvitation
ile birlikte, Proposal
ve Payment
de gereklidir.
const aliceSeat = await E(zoe).offer(
creatorInvitation,
aliceProposal,
alicePayments
);
CreatorInvitation, makeFundedPairInvitation
fonksiyonu için davetiye ile birlikte, getInvitationDetails
metodu ile erişilebilen bir özel obje
döndürür. Bu obje, belirlenen uzun ve kısa miktarları içerir.
Bu değerler teklif teklifinde want
özelliği olarak kullanılır. give
özelliği söz konusu olduğunda, bu, sözleşme şartlarında settlementAmount
olarak tanımlanan değerden oluşur.
const invitationDetail = await E(zoe).getInvitationDetails(creatorInvitation);
const longOptionAmount = invitationDetail.longAmount;
const shortOptionAmount = invitationDetail.shortAmount;
const aliceProposal = harden({
want: { LongOption: longOptionAmount, ShortOption: shortOptionAmount },
give: { Collateral: bucks(300n) },
});
Teklifin ödemesi
, genellikle, teklif teklifinin give
özelliğinde tanımlanan miktarın basılmış ödemesidir. Bu durumda, spread çağrısının teminatı
.
const aliceBucksPayment = bucksMint.mintPayment(bucks(300n));
const alicePayments = { Collateral: aliceBucksPayment };
Teklif yapıldığında, iki opsiyon pozisyonunu içeren bir ödeme döndürülür. Pozisyonlar, ücretsiz olarak kullanılabilen davetiyelerdir ve Collateral anahtar kelimesi altında opsiyon ödemelerini sağlarlar.
const { LongOption, ShortOption } = await aliceSeat.getPayouts();
Bu iki davetiye, ev sahibi sözleşmeniz tarafından yönetilebilir ve uygulamanızın bağlamına bağlı olarak birçok farklı finansal enstrüman oluşturmanıza olanak sağlar.
Basit Takas
simpleExchange
sözleşmesi, Generic Sales/Trading Contracts package
'ten, ikinci bir varlığı fiyat olarak kullanarak bir varlığı ticaret için basit bir değişimdir.
order book
, yeni bir sipariş oluşturulduğunda eşleşen satış
ve alış
siparişlerini arayan iki basit liste oluşturur. Herkes sipariş oluşturabilir veya doldurabilir ve mevcut sipariş listesini görmek için bir bildirim sistemi vardır.
Daha fazla ayrıntı için, şunları okumanızı öneririz:
const issuerKeywordRecord = harden({
Underlying: simoleanIssuer,
Collateral: bucksIssuer,
Strike: moolaIssuer,
Quote: await E(priceAuthority).getQuoteIssuer(
brands.get("simoleans"),
brands.get("moola")
),
});
issuerKeywordRecord
, simoleanIssuer
olarak belirlenen Underlying
, bucksIssuer
olarak belirlenen Collateral
, moolaIssuer
olarak belirlenen Strike
ve priceAuthority
'den alınan Quote
olmak üzere belirli Issuer
'ları belirler.
terms
tarafına gelince, bunlar aşağıdakileri içerir:
expiration
: Opsiyonun kullanılabilir olduğu süreyi belirler.priceAuthority
: Süre sonunda, temel varlığın değerini strike para biriminde veren bir Fiyat Teklifi çıkarır.underlyingAmount
: Takip edilen varlığın fiyatı.strikePrice1
vestrikePrice2
: Sırasıyla kısa ve uzun olarak tanımlanan değerler.settlementAmount
: Opsiyonların sahipleri arasında bölünen ve fon sağlayıcı tarafından yatırılan teminat miktarı.timer
:priceAuthority
tarafından tanınan zamanlayıcı.
const terms = harden({
expiration: 2n,
underlyingAmount: simoleans(2n),
priceAuthority,
strikePrice1: moola(60n),
strikePrice2: moola(100n),
settlementAmount: bucks(300n),
timer: manualTimer,
});
Ev sahibi sözleşme, LongOption
ve ShortOption
adında iki opsiyonu geri almak için fundedCallSpread'e bir teklif
yapar.
Teklifi oluşturmak için, startInstance() çağrıldığında geri dönen creatorInvitation
ile birlikte, Proposal
ve Payment
de gereklidir.
const aliceSeat = await E(zoe).offer(
creatorInvitation,
aliceProposal,
alicePayments
);
CreatorInvitation, makeFundedPairInvitation
fonksiyonu için davetiye ile birlikte, getInvitationDetails
metodu ile erişilebilen bir özel obje
döndürür. Bu obje, belirlenen uzun ve kısa miktarları içerir.
Bu değerler teklif teklifinde want
özelliği olarak kullanılır. give
özelliği söz konusu olduğunda, bu, sözleşme şartlarında settlementAmount
olarak tanımlanan değerden oluşur.
const invitationDetail = await E(zoe).getInvitationDetails(creatorInvitation);
const longOptionAmount = invitationDetail.longAmount;
const shortOptionAmount = invitationDetail.shortAmount;
const aliceProposal = harden({
want: { LongOption: longOptionAmount, ShortOption: shortOptionAmount },
give: { Collateral: bucks(300n) },
});
Teklifin ödemesi
, genellikle, teklif teklifinin give
özelliğinde tanımlanan miktarın basılmış ödemesidir. Bu durumda, spread çağrısının teminatı
.
const aliceBucksPayment = bucksMint.mintPayment(bucks(300n));
const alicePayments = { Collateral: aliceBucksPayment };
Teklif yapıldığında, iki opsiyon pozisyonunu içeren bir ödeme döndürülür. Pozisyonlar, ücretsiz olarak kullanılabilen davetiyelerdir ve Collateral anahtar kelimesi altında opsiyon ödemelerini sağlarlar.
const { LongOption, ShortOption } = await aliceSeat.getPayouts();
Bu iki davetiye, ev sahibi sözleşmeniz tarafından yönetilebilir ve uygulamanızın bağlamına bağlı olarak birçok farklı finansal enstrüman oluşturmanıza olanak sağlar.
Basit Takas
simpleExchange
sözleşmesi, Generic Sales/Trading Contracts package
'ten, ikinci bir varlığı fiyat olarak kullanarak bir varlığı ticaret için basit bir değişimdir.
order book
, yeni bir sipariş oluşturulduğunda eşleşen satış
ve alış
siparişlerini arayan iki basit liste oluşturur. Herkes sipariş oluşturabilir veya doldurabilir ve mevcut sipariş listesini görmek için bir bildirim sistemi vardır.
Daha fazla ayrıntı için, şunları okumanızı öneririz:
Fiyat Teklifi Bildirimi
makeQuoteNotifier fonksiyonu, altta yatan bir bildiriciyi kapsayan bir quote bildirici
oluşturur. Quote bildiricinin amacı, iki varlık arasındaki oranın fiyat tekliflerinin zamanla güncellenen bir akışını sağlamaktır.
MakeQuoteNotifier() iki parametre alır: amountIn
ve brandOut
. AmountIn markası ve brandOut, assertBrands fonksiyonunu kullanarak desteklenen çiftin kontrol edilmesi için kontrol edilir.
Daha sonra, altta yatan bildiricinin getUpdateSince
metodu, metot her çağrıldığında yeni bir "teklif" oluşturacak şekilde geçersiz kılınır. Teklif, createQuote
fonksiyonunu kullanarak oluşturulur ve teklif sabitine geçirilir. Metot, teklifin değerini ve güncellenmiş sayıyı içeren yeni bir kayıt döndürür.
Son olarak, yeni bir bildirici objesi oluşturulur ve specificBaseNotifier
'ın metotları ve özellikleri ile birlikte döndürülür.
makeQuoteNotifier(amountIn, brandOut) {
AmountMath.coerce(actualBrandIn, amountIn);
assertBrands(amountIn.brand, brandOut);
// Wrap our underlying notifier with specific quotes.
const specificBaseNotifier = harden({
async getUpdateSince(updateCount = undefined) {
// We use the same updateCount as our underlying notifier.
const record = await E(notifier).getUpdateSince(updateCount);
// We create a quote inline.
const quote = createQuote(calcAmountOut => ({
amountIn,
amountOut: calcAmountOut(amountIn),
}));
assert(quote);
const value = await quote;
return harden({
value,
updateCount: record.updateCount,
});
},
});
/** @type {Notifier<PriceQuote>} */
const specificNotifier = Far('QuoteNotifier', {
...makeNotifier(specificBaseNotifier),
// TODO stop exposing baseNotifier methods directly.
...specificBaseNotifier,
});
return specificNotifier;
}
Aşağıdaki test, scaled price authority, makeQuoteNotifier metodunun nasıl kullanılacağını göstermektedir. MakeQuoteNotifier tarafından döndürülen bildirici nesnesinin getUpdateSince metodunu çağırarak, güncellenmiş teklif kaydı ve güncellenmiş sayı ile bir promise döndürecektir.
test('scaled price authority', /** @param {ExecutionContext} t */ async t => {
const pa = await E(scaledPrice.publicFacet).getPriceAuthority();
const notifier = E(pa).makeQuoteNotifier(
AmountMath.make(t.context.ibcAtom.brand, 10n ** 6n),
t.context.run.brand,
);
const {
value: { quoteAmount: qa1 },
updateCount: uc1,
} = await E(notifier).getUpdateSince();
t.deepEqual(qa1.value, [
{
amountIn: { brand: t.context.ibcAtom.brand, value: 10n ** 6n },
amountOut: { brand: t.context.run.brand, value: 35_610_000n },
timer,
timestamp: 0n,
},
]);
...
});
quoteWanted
quoteWanted fonksiyonu, verilen bir brandIn
ve amountOut
için fiyat teklifi hesaplar.
Bu fonksiyon, yukarıdaki fonksiyonla benzerdir, tek fark, createQuote fonksiyonunun iki parametre calcAmountOut
ve calcAmountIn
almasıdır. Geri çağırma fonksiyonu, minimum bir amountOut garantileyen bir amountIn değerini belirlemek için calcAmountIn'i kullanır ve ardından verilen amountIn için gerçek amountOut'u hesaplamak için calcAmountOut'u kullanır.
Fonksiyon, hem amountIn hem de amountOut ile fiyat teklifini döndürür.
async quoteWanted(brandIn, amountOut) {
AmountMath.coerce(actualBrandOut, amountOut);
assertBrands(brandIn, amountOut.brand);
await E(notifier).getUpdateSince();
const quote = createQuote((calcAmountOut, calcAmountIn) => {
// En az amountOut garantileyen bir amountIn belirlememiz gerekiyor.
const amountIn = calcAmountIn(amountOut);
const actualAmountOut = calcAmountOut(amountIn);
AmountMath.isGTE(actualAmountOut, amountOut) ||
assert.fail(
X`Hesaplama olan ${actualAmountOut}, beklenen ${amountOut}'u karşılamadı`,
);
return { amountIn, amountOut };
});
assert(quote);
return quote;
},
Aşağıdaki test, priceAuthority quoteWanted, quoteWanted metodunu nasıl kullanılacağını gösterir.
BrandIn olarak moolaBrand ve amountOut olarak bucks(400n) verilerek beklenen teklif döndürülür.
Bu örnekte, teklif miktarı quote.quoteAmount.value[0]
özelliği kullanılarak erişilir.
test("priceAuthority quoteWanted", async (t) => {
const { moola, bucks, brands } = setup();
const moolaBrand = brands.get("moola");
assert(moolaBrand);
const manualTimer = buildManualTimer(t.log, 0n, { eventLoopIteration });
const priceAuthority = await makeTestPriceAuthority(
brands,
[20, 55],
manualTimer
);
await E(manualTimer).tick();
const quote = await E(priceAuthority).quoteWanted(moolaBrand, bucks(400n));
const quoteAmount = quote.quoteAmount.value[0];
t.is(1n, quoteAmount.timestamp);
assertAmountsEqual(t, bucks(400n), quoteAmount.amountOut);
assertAmountsEqual(t, moola(20n), quoteAmount.amountIn);
});
Promise Fiyat Teklifi
priceAuthority
'nin belirli koşulların, geliştirici tarafından belirlenen, gerçekleştiğinde çözülecek bir promise
döndüren birkaç metodu vardır.
Bu metodlar:
quoteWhenLT: makeQuoteWhenOut(isLT),
quoteWhenLTE: makeQuoteWhenOut(isLTE),
quoteWhenGTE: makeQuoteWhenOut(isGTE),
quoteWhenGT: makeQuoteWhenOut(isGT),
mutableQuoteWhenLT: makeMutableQuote(isLT),
mutableQuoteWhenLTE: makeMutableQuote(isLTE),
mutableQuoteWhenGT: makeMutableQuote(isGT),
mutableQuoteWhenGTE: makeMutableQuote(isGTE),
Yukarıdaki metodlar tarafından beklenen parametreler, compareAmountsFn
olarak adlandırılan, AmountMath kütüphanesi kullanılarak oluşturulur. İlgili promise için koşulu bu parametre belirler.
/**
* @callback CompareAmount
* @param {Amount} amount
* @param {Amount} amountLimit
* @returns {boolean}
*/
/** @type {CompareAmount} */
const isLT = (amount, amountLimit) => !AmountMath.isGTE(amount, amountLimit);
/** @type {CompareAmount} */
const isLTE = (amount, amountLimit) => AmountMath.isGTE(amountLimit, amount);
/** @type {CompareAmount} */
const isGTE = (amount, amountLimit) => AmountMath.isGTE(amount, amountLimit);
/** @type {CompareAmount} */
const isGT = (amount, amountLimit) => !AmountMath.isGTE(amountLimit, amount);
quoteWhen
makeQuoteWhenOut fonksiyonu bir compareAmountsFn
alır ve bir iç fonksiyon olan quoteWhenOutTrigger
'ı döndürür. İç fonksiyon, amountIn
ve amountOutLimit
olmak üzere iki argüman alan asenkron bir fonksiyondur.
Fonksiyon, makePromiseKit
kullanarak bir Promise objesi triggerPK
oluşturur. Ardından createInstantQuote
alarak bir trigger
adlı asenkron bir fonksiyon oluşturur. Bu fonksiyon, createInstantQuote ve calcAmountOut'a dayanarak bir teklif oluşturmaya çalışır:
Eğer tetikleyiciler seti tetikleyiciyi içermiyorsa, tetikleyici zaten ateşlendiği için hemen undefined döndürür.
Eğer compareAmountsFn, calcAmountOut(amountIn) ve amountOutLimit geçildiğinde false dönerse, tetikleyici henüz ateşlememeli çünkü undefined döner.
Eğer compareAmountsFn true dönerse, fonksiyon, amountIn ve amountOut özelliklerine sahip bir obje döndürerek bir teklif oluştur.
Eğer compareAmountsFn doğru dönerse, işlev, amountIn ve amountOut özelliklerine sahip bir nesne döndürerek bir teklif oluşturur.
Eğer createInstantQuote'nun döndürdüğü değer null ise, undefined döndürür.
Eğer try bloğunda bir istisna atılırsa, tetikleyici vaadi reddedilir ve tetikleyici, tetikleyiciler kümesinden silinir.
Sonunda, tetikleyici tetikleyiciler kümesine eklenir ve tetikleyici fonksiyonu, argümanı olarak createQuote ile hemen çalıştırılır. İşlev daha sonra Promise nesnesi olan triggerPK'yi döndürecektir.
Aşağıdaki test, priceAuthority quoteWhenLT, quoteWhenLT
metodunun nasıl kullanılacağını gösterir.
AmountIn (moola(1n)) ve amountOutLimit (bucks(30n)) sağlayarak, bir PriceQuote vaadi döndürecektir.
Zaman, koşul tetiklenene kadar ileriye taşınacaktır (await E(manualTimer).tick()).
test("priceAuthority quoteWhenLT", async (t) => {
const { moola, bucks, brands } = setup();
const manualTimer = buildManualTimer(t.log, 0n, { eventLoopIteration });
const priceAuthority = await makeTestPriceAuthority(
brands,
[40, 30, 29],
manualTimer
);
E(priceAuthority)
.quoteWhenLT(moola(1n), bucks(30n))
.then((quote) => {
const quoteInAmount = quote.quoteAmount.value[0];
// @ts-expect-error could be TimestampRecord
t.is(3n, manualTimer.getCurrentTimestamp());
t.is(3n, quoteInAmount.timestamp);
assertAmountsEqual(t, bucks(29n), quoteInAmount.amountOut);
assertAmountsEqual(t, moola(1n), quoteInAmount.amountIn);
});
await E(manualTimer).tick();
await E(manualTimer).tick();
await E(manualTimer).tick();
await E(manualTimer).tick();
});
mutableQuoteWhen
makeMutableQuote fonksiyonu, yukarıdaki işlevle çok benzer, ancak çağrıldığında, mutableQuoteWhenOutTrigger
adında yeni bir işlev döndürür, bu da bir mutableQuote
nesnesi döndürür.
MutableQuote nesnesi, üç metodla oluşturulur: cancel
, updateLevel
, ve getPromise
:
- Cancel metodunu, mutableQuote ile ilişkilendirilmiş vaadi reddetmek için kullanılır.
- UpdateLevel metodunu, amountIn ve amountOutLimit değerlerini değiştirmek ve tetikleyiciyi yeniden ateşlemek için kullanılır.
- GetPromise metodunu, mutableQuote ile ilişkilendirilmiş vaadi döndürmek için kullanılır.
Aşağıdaki test, temutableQuoteWhenLT: brands in/out matchst, mutableQuoteWhenLT
metodunun nasıl kullanılacağını gösterir.
AmountIn'i, AmountMath.make(t.context.ibcAtom.brand, 10n ** 6n), ve amountOutLimit'i, AmountMath.make(t.context.ibcAtom.brand, 10n ** 6n), sağlayarak, bir MutableQuote vaadi döndürecektir.
Zaman, await E(timer).tick() kullanılarak ileriye taşınacak, bu da koşulun tetiklenmesine izin verecektir.
test("mutableQuoteWhenLT: markalar giriş/çıkışta eşleşiyor", /** @param {ExecutionContext} t */ async (t) => {
const timer = buildManualTimer(t.log);
const makeSourcePrice = (valueIn, valueOut) =>
makeRatio(valueOut, t.context.usdBrand, valueIn, t.context.atomBrand);
const sourcePriceAuthority = makeManualPriceAuthority({
actualBrandIn: t.context.atomBrand,
actualBrandOut: t.context.usdBrand,
initialPrice: makeSourcePrice(10n ** 5n, 35_6100n),
timer,
});
const scaledPrice = await E(t.context.zoe).startInstance(
t.context.scaledPriceInstallation,
undefined,
{
sourcePriceAuthority,
scaleIn: makeRatio(
10n ** 5n,
t.context.atomBrand,
10n ** 6n,
t.context.ibcAtom.brand
),
scaleOut: makeRatio(
10n ** 4n,
t.context.usdBrand,
10n ** 6n,
t.context.run.brand
),
}
);
const pa = await E(scaledPrice.publicFacet).getPriceAuthority();
const mutableQuote = E(pa).mutableQuoteWhenLT(
AmountMath.make(t.context.ibcAtom.brand, 10n ** 6n),
AmountMath.make(t.context.run.brand, 32_430_100n)
);
const sourceNotifier = E(sourcePriceAuthority).makeQuoteNotifier(
AmountMath.make(t.context.atomBrand, 10n ** 5n),
t.context.usdBrand
);
const {
value: { quoteAmount: sqa1 },
updateCount: suc1,
} = await E(sourceNotifier).getUpdateSince();
t.deepEqual(sqa1.value, [
{
amountIn: { brand: t.context.atomBrand, value: 10n ** 5n },
amountOut: { brand: t.context.usdBrand, value: 35_6100n },
timer,
timestamp: 0n,
},
]);
await E(timer).tick();
sourcePriceAuthority.setPrice(makeSourcePrice(10n ** 5n, 30_4301n));
const { quoteAmount: qa2 } = await E(mutableQuote).getPromise();
t.deepEqual(qa2.value, [
{
amountIn: { brand: t.context.ibcAtom.brand, value: 1_000_000n },
amountOut: { brand: t.context.run.brand, value: 30_430_100n },
timer,
timestamp: 1n,
},
]);
// kaynak fiyat teklifini kontrol et
const {
value: { quoteAmount: sqa2 },
} = await E(sourceNotifier).getUpdateSince(suc1);
t.deepEqual(sqa2.value, [
{
amountIn: { brand: t.context.atomBrand, value: 1_00000n },
amountOut: { brand: t.context.usdBrand, value: 30_4301n },
timer,
timestamp: 1n,
},
]);
});
Diğer örnekler için aşağıdaki testlere göz atmanızı öneririz:
makeQuoteWhenOut
ve makeMutableQuote
işlevleri arasındaki ana fark, makeQuoteWhenOut
'un belirli bir koşul yerine getirildiğinde bir teklifle çözülen bir söz veren quoteWhenOutTrigger
işlevi oluşturmasıdır, buna karşın makeMutableQuote
bir mutableQuoteWhenOutTrigger
işlevi oluşturur ki bu da güncellenebilen ve iptal edilebilen bir mutable teklif verir.
Manuel Fiyat Otoritesi
makeManualPriceAuthority işlevi, PriceAuthority
arabirimini uygulayan ve geri dönen bir nesne oluşturan ve döndüren bir manuel fiyat otoritesini temsil eden bir nesne döndürür, aşağıdaki ek yöntemle:
- setPrice: talep edilen varlık oranının mevcut fiyatını değiştirmeyi sağlayan bir işlev.
createQuote
işlevi, mevcut fiyat için bir fiyat teklifi oluşturur. Teklif, bir teklifi alarak quoteMint
kullanarak ödemeye dönüştüren ve quote payment
ve quote amount
döndüren authenticateQuote
işlevi kullanılarak doğrulanır. calcAmountOut
ve calcAmountIn
işlevleri, mevcut fiyata dayalı olarak çıktı ve giriş miktarlarını hesaplar.
Son olarak, timer, createQuote işlevi, giriş ve çıkış markaları, teklif veren ve bildiriciyi içeren priceAuthorityOptions
nesnesini alan makeOnewayPriceAuthorityKit
yardımcı programı kullanılarak bir priceAuthority nesnesi oluşturulur.
PriceAuthority, setPrice yöntemiyle birlikte döndürülür.
/**
*
* @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;
...
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,
});
}
Aşağıdaki ölçeklendirilmiş fiyat yetkilisi testi, nasıl yapılacağını gösterir "makeManualPriceAuthority" işlevini kullanın. makeManualPriceAuthority(), makeQuoteNotifier yöntemini kullanarak quoteNotifier'ı almak ve setPrice yöntemini kullanarak fiyatı güncellemek için kullanılan bir manualPriceAuthority, "sourcePriceAuthority" döndürür.
test("scaled price authority", /** @param {ExecutionContext} t */ async (t) => {
const timer = buildManualTimer(t.log);
const makeSourcePrice = (valueIn, valueOut) =>
makeRatio(valueOut, t.context.usdBrand, valueIn, t.context.atomBrand);
const sourcePriceAuthority = makeManualPriceAuthority({
actualBrandIn: t.context.atomBrand,
actualBrandOut: t.context.usdBrand,
initialPrice: makeSourcePrice(10n ** 5n, 35_6100n),
timer,
});
const scaledPrice = await E(t.context.zoe).startInstance(
t.context.scaledPriceInstallation,
undefined,
{
sourcePriceAuthority,
scaleIn: makeRatio(
10n ** 5n,
t.context.atomBrand,
10n ** 6n,
t.context.ibcAtom.brand
),
scaleOut: makeRatio(
10n ** 4n,
t.context.usdBrand,
10n ** 6n,
t.context.run.brand
),
}
);
const pa = await E(scaledPrice.publicFacet).getPriceAuthority();
const notifier = E(pa).makeQuoteNotifier(
AmountMath.make(t.context.ibcAtom.brand, 10n ** 6n),
t.context.run.brand
);
const sourceNotifier = E(sourcePriceAuthority).makeQuoteNotifier(
AmountMath.make(t.context.atomBrand, 10n ** 5n),
t.context.usdBrand
);
const {
value: { quoteAmount: qa1 },
updateCount: uc1,
} = await E(notifier).getUpdateSince();
t.deepEqual(qa1.value, [
{
amountIn: { brand: t.context.ibcAtom.brand, value: 10n ** 6n },
amountOut: { brand: t.context.run.brand, value: 35_610_000n },
timer,
timestamp: 0n,
},
]);
const {
value: { quoteAmount: sqa1 },
updateCount: suc1,
} = await E(sourceNotifier).getUpdateSince();
t.deepEqual(sqa1.value, [
{
amountIn: { brand: t.context.atomBrand, value: 10n ** 5n },
amountOut: { brand: t.context.usdBrand, value: 35_6100n },
timer,
timestamp: 0n,
},
]);
await E(timer).tick();
sourcePriceAuthority.setPrice(makeSourcePrice(10n ** 5n, 32_4301n));
const {
value: { quoteAmount: qa2 },
} = await E(notifier).getUpdateSince(uc1);
t.deepEqual(qa2.value, [
{
amountIn: { brand: t.context.ibcAtom.brand, value: 1_000_000n },
amountOut: { brand: t.context.run.brand, value: 32_430_100n },
timer,
timestamp: 1n,
},
]);
const {
value: { quoteAmount: sqa2 },
} = await E(sourceNotifier).getUpdateSince(suc1);
t.deepEqual(sqa2.value, [
{
amountIn: { brand: t.context.atomBrand, value: 1_00000n },
amountOut: { brand: t.context.usdBrand, value: 32_4301n },
timer,
timestamp: 1n,
},
]);
});