@indigo-labs/indigo-sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.nvmrc +1 -0
- package/.prettierrc +6 -0
- package/README.md +21 -0
- package/babel.config.cjs +13 -0
- package/dist/contracts/cdp-creator.d.ts +9 -0
- package/dist/contracts/cdp-creator.js +58 -0
- package/dist/contracts/cdp.d.ts +22 -0
- package/dist/contracts/cdp.js +542 -0
- package/dist/contracts/collector.d.ts +9 -0
- package/dist/contracts/collector.js +52 -0
- package/dist/contracts/gov.d.ts +5 -0
- package/dist/contracts/gov.js +50 -0
- package/dist/contracts/interest-oracle.d.ts +8 -0
- package/dist/contracts/interest-oracle.js +39 -0
- package/dist/contracts/price-oracle.d.ts +5 -0
- package/dist/contracts/price-oracle.js +18 -0
- package/dist/contracts/treasury.d.ts +9 -0
- package/dist/contracts/treasury.js +56 -0
- package/dist/helpers/asset-helpers.d.ts +11 -0
- package/dist/helpers/asset-helpers.js +23 -0
- package/dist/helpers/cdp-helpers.d.ts +5 -0
- package/dist/helpers/cdp-helpers.js +5 -0
- package/dist/helpers/helpers.d.ts +4 -0
- package/dist/helpers/helpers.js +14 -0
- package/dist/helpers/lucid-utils.d.ts +6 -0
- package/dist/helpers/lucid-utils.js +18 -0
- package/dist/helpers/time-helpers.d.ts +3 -0
- package/dist/helpers/time-helpers.js +3 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +23 -0
- package/dist/scripts/cdp-creator-validator.d.ts +6 -0
- package/dist/scripts/cdp-creator-validator.js +6 -0
- package/dist/scripts/cdp-validator.d.ts +6 -0
- package/dist/scripts/cdp-validator.js +6 -0
- package/dist/scripts/collector-validator.d.ts +6 -0
- package/dist/scripts/collector-validator.js +5 -0
- package/dist/scripts/interest-oracle-validator.d.ts +6 -0
- package/dist/scripts/interest-oracle-validator.js +5 -0
- package/dist/scripts/treasury-validator.d.ts +6 -0
- package/dist/scripts/treasury-validator.js +5 -0
- package/dist/types/generic.d.ts +10 -0
- package/dist/types/generic.js +1 -0
- package/dist/types/indigo/cdp.d.ts +37 -0
- package/dist/types/indigo/cdp.js +1 -0
- package/dist/types/indigo/gov.d.ts +20 -0
- package/dist/types/indigo/gov.js +1 -0
- package/dist/types/indigo/interest-oracle.d.ts +5 -0
- package/dist/types/indigo/interest-oracle.js +1 -0
- package/dist/types/indigo/price-oracle.d.ts +4 -0
- package/dist/types/indigo/price-oracle.js +1 -0
- package/dist/types/system-params.d.ts +217 -0
- package/dist/types/system-params.js +1 -0
- package/jest.config.js +13 -0
- package/package.json +46 -0
- package/src/contracts/cdp-creator.ts +86 -0
- package/src/contracts/cdp.ts +892 -0
- package/src/contracts/collector.ts +91 -0
- package/src/contracts/gov.ts +58 -0
- package/src/contracts/interest-oracle.ts +49 -0
- package/src/contracts/price-oracle.ts +24 -0
- package/src/contracts/treasury.ts +95 -0
- package/src/helpers/asset-helpers.ts +28 -0
- package/src/helpers/cdp-helpers.ts +9 -0
- package/src/helpers/helpers.ts +17 -0
- package/src/helpers/lucid-utils.ts +24 -0
- package/src/helpers/time-helpers.ts +3 -0
- package/src/index.ts +23 -0
- package/src/scripts/cdp-creator-validator.ts +9 -0
- package/src/scripts/cdp-validator.ts +9 -0
- package/src/scripts/collector-validator.ts +8 -0
- package/src/scripts/interest-oracle-validator.ts +8 -0
- package/src/scripts/treasury-validator.ts +8 -0
- package/src/types/generic.ts +13 -0
- package/src/types/indigo/cdp.ts +33 -0
- package/src/types/indigo/gov.ts +21 -0
- package/src/types/indigo/interest-oracle.ts +5 -0
- package/src/types/indigo/price-oracle.ts +4 -0
- package/src/types/system-params.ts +228 -0
- package/tests/data/system-params.json +989 -0
- package/tests/datums.test.ts +51 -0
- package/tests/hash-checks.test.ts +17 -0
- package/tests/interest-calculations.test.ts +143 -0
- package/tsconfig.json +35 -0
|
@@ -0,0 +1,542 @@
|
|
|
1
|
+
import { applyParamsToScript, Constr, Data, fromText, toText, validatorToAddress, validatorToScriptHash, } from '@lucid-evolution/lucid';
|
|
2
|
+
import { IAssetHelpers } from '../helpers/asset-helpers';
|
|
3
|
+
import { PriceOracleContract } from './price-oracle';
|
|
4
|
+
import { CDPCreatorContract } from './cdp-creator';
|
|
5
|
+
import { CollectorContract } from './collector';
|
|
6
|
+
import { InterestOracleContract } from './interest-oracle';
|
|
7
|
+
import { GovContract } from './gov';
|
|
8
|
+
import { TreasuryContract } from './treasury';
|
|
9
|
+
import { addrDetails, getRandomElement, scriptRef } from '../helpers/lucid-utils';
|
|
10
|
+
import { calculateFeeFromPercentage } from '../helpers/helpers';
|
|
11
|
+
import { _cdpValidator } from '../scripts/cdp-validator';
|
|
12
|
+
export class CDPContract {
|
|
13
|
+
static async openPosition(asset, collateralAmount, mintedAmount, params, lucid, assetRef, priceOracleRef, interestOracleRef, cdpCreatorRef, collectorRef) {
|
|
14
|
+
const [pkh, skh] = await addrDetails(lucid);
|
|
15
|
+
const now = Date.now();
|
|
16
|
+
const assetOut = await (assetRef
|
|
17
|
+
? IAssetHelpers.findIAssetByRef(assetRef, params, lucid)
|
|
18
|
+
: IAssetHelpers.findIAssetByName(asset, params, lucid));
|
|
19
|
+
// Fail if delisted asset
|
|
20
|
+
if ('getOnChainPrice' in assetOut.datum.price)
|
|
21
|
+
return Promise.reject('Trying to open CDP against delisted asset');
|
|
22
|
+
const oracleAsset = assetOut.datum.price;
|
|
23
|
+
const oracleOut = priceOracleRef
|
|
24
|
+
? (await lucid.utxosByOutRef([priceOracleRef]))[0]
|
|
25
|
+
: await lucid.utxoByUnit(oracleAsset[0].unCurrencySymbol +
|
|
26
|
+
fromText(oracleAsset[1].unTokenName));
|
|
27
|
+
if (!oracleOut.datum)
|
|
28
|
+
return Promise.reject('Price Oracle datum not found');
|
|
29
|
+
const oracleDatum = PriceOracleContract.decodePriceOracleDatum(oracleOut.datum);
|
|
30
|
+
const interestOracleAsset = assetOut.datum.interestOracle;
|
|
31
|
+
const interestOracleOut = interestOracleRef
|
|
32
|
+
? (await lucid.utxosByOutRef([interestOracleRef]))[0]
|
|
33
|
+
: await lucid.utxoByUnit(interestOracleAsset[0].unCurrencySymbol +
|
|
34
|
+
fromText(interestOracleAsset[1].unTokenName));
|
|
35
|
+
if (!interestOracleOut.datum)
|
|
36
|
+
return Promise.reject('Interest Oracle datum not found');
|
|
37
|
+
const interestOracleDatum = InterestOracleContract.decodeInterestOracleDatum(interestOracleOut.datum);
|
|
38
|
+
const cdpCreatorOut = getRandomElement(cdpCreatorRef
|
|
39
|
+
? await lucid.utxosByOutRef([cdpCreatorRef])
|
|
40
|
+
: await lucid.utxosAtWithUnit(CDPCreatorContract.address(params.cdpCreatorParams, lucid), params.cdpCreatorParams.cdpCreatorNft[0].unCurrencySymbol +
|
|
41
|
+
fromText(params.cdpCreatorParams.cdpCreatorNft[1].unTokenName)));
|
|
42
|
+
const cdpCreatorRedeemer = CDPCreatorContract.redeemer(pkh, mintedAmount, collateralAmount, BigInt(now));
|
|
43
|
+
const cdpCreatorScriptRefUtxo = await CDPCreatorContract.scriptRef(params.scriptReferences, lucid);
|
|
44
|
+
const cdpAddress = CDPContract.address(params.cdpParams, lucid, skh);
|
|
45
|
+
const cdpToken = params.cdpParams.cdpAuthToken[0].unCurrencySymbol +
|
|
46
|
+
fromText(params.cdpParams.cdpAuthToken[1].unTokenName);
|
|
47
|
+
const cdpValue = {
|
|
48
|
+
lovelace: collateralAmount,
|
|
49
|
+
};
|
|
50
|
+
cdpValue[cdpToken] = 1n;
|
|
51
|
+
const newSnapshot = InterestOracleContract.calculateUnitaryInterestSinceOracleLastUpdated(BigInt(now), interestOracleDatum) + interestOracleDatum.unitaryInterest;
|
|
52
|
+
const cdpDatum = CDPContract.datum(pkh, asset, mintedAmount, {
|
|
53
|
+
type: 'ActiveCDPInterestTracking',
|
|
54
|
+
last_settled: BigInt(now),
|
|
55
|
+
unitary_interest_snapshot: newSnapshot
|
|
56
|
+
});
|
|
57
|
+
const assetToken = params.cdpParams.cdpAssetSymbol.unCurrencySymbol + fromText(asset);
|
|
58
|
+
const cdpTokenMintValue = {};
|
|
59
|
+
cdpTokenMintValue[cdpToken] = 1n;
|
|
60
|
+
const iassetTokenMintValue = {};
|
|
61
|
+
iassetTokenMintValue[assetToken] = BigInt(mintedAmount);
|
|
62
|
+
const cdpAuthTokenScriptRefUtxo = await CDPContract.cdpAuthTokenRef(params.scriptReferences, lucid);
|
|
63
|
+
const iAssetTokenScriptRefUtxo = await CDPContract.assetTokenRef(params.scriptReferences, lucid);
|
|
64
|
+
const debtMintingFee = calculateFeeFromPercentage(BigInt(assetOut.datum.debtMintingFeePercentage.getOnChainInt), mintedAmount * oracleDatum.price);
|
|
65
|
+
// Oracle timestamp - 20s (length of a slot)
|
|
66
|
+
const cappedValidateTo = oracleDatum.expiration - 20001n;
|
|
67
|
+
const timeValidFrom = now - 1_000;
|
|
68
|
+
const timeValidTo_ = now + params.cdpCreatorParams.biasTime - 1_000;
|
|
69
|
+
const timeValidTo = cappedValidateTo <= timeValidFrom
|
|
70
|
+
? timeValidTo_
|
|
71
|
+
: Math.min(timeValidTo_, Number(cappedValidateTo));
|
|
72
|
+
const tx = lucid
|
|
73
|
+
.newTx()
|
|
74
|
+
.collectFrom([cdpCreatorOut], Data.to(cdpCreatorRedeemer))
|
|
75
|
+
.readFrom([cdpCreatorScriptRefUtxo])
|
|
76
|
+
.pay.ToContract(cdpAddress, { kind: 'inline', value: Data.to(cdpDatum) }, cdpValue)
|
|
77
|
+
.pay.ToContract(cdpCreatorOut.address, { kind: 'inline', value: cdpCreatorOut.datum }, cdpCreatorOut.assets)
|
|
78
|
+
.readFrom([oracleOut, interestOracleOut, assetOut.utxo])
|
|
79
|
+
.mintAssets(cdpTokenMintValue, Data.to(new Constr(0, [])))
|
|
80
|
+
.readFrom([cdpAuthTokenScriptRefUtxo])
|
|
81
|
+
.mintAssets(iassetTokenMintValue, Data.to(new Constr(0, [])))
|
|
82
|
+
.readFrom([iAssetTokenScriptRefUtxo])
|
|
83
|
+
.addSignerKey(pkh.hash)
|
|
84
|
+
.validFrom(Number(now - 60_000))
|
|
85
|
+
.validTo(Number(timeValidTo));
|
|
86
|
+
if (debtMintingFee > 0) {
|
|
87
|
+
await CollectorContract.feeTx(debtMintingFee, lucid, params, tx, collectorRef);
|
|
88
|
+
}
|
|
89
|
+
return tx;
|
|
90
|
+
}
|
|
91
|
+
static async deposit(cdpRef, amount, params, lucid, assetRef, priceOracleRef, interestOracleRef, collectorRef, govRef, treasuryRef) {
|
|
92
|
+
return CDPContract.adjust(cdpRef, amount, 0n, params, lucid, assetRef, priceOracleRef, interestOracleRef, collectorRef, govRef, treasuryRef);
|
|
93
|
+
}
|
|
94
|
+
static async withdraw(cdpRef, amount, params, lucid, assetRef, priceOracleRef, interestOracleRef, collectorRef, govRef, treasuryRef) {
|
|
95
|
+
return CDPContract.adjust(cdpRef, -amount, 0n, params, lucid, assetRef, priceOracleRef, interestOracleRef, collectorRef, govRef, treasuryRef);
|
|
96
|
+
}
|
|
97
|
+
static async mint(cdpRef, amount, params, lucid, assetRef, priceOracleRef, interestOracleRef, collectorRef, govRef, treasuryRef) {
|
|
98
|
+
return CDPContract.adjust(cdpRef, 0n, amount, params, lucid, assetRef, priceOracleRef, interestOracleRef, collectorRef, govRef, treasuryRef);
|
|
99
|
+
}
|
|
100
|
+
static async burn(cdpRef, amount, params, lucid, assetRef, priceOracleRef, interestOracleRef, collectorRef, govRef, treasuryRef) {
|
|
101
|
+
return CDPContract.adjust(cdpRef, 0n, -amount, params, lucid, assetRef, priceOracleRef, interestOracleRef, collectorRef, govRef, treasuryRef);
|
|
102
|
+
}
|
|
103
|
+
static async adjust(cdpRef, collateralAmount, mintAmount, params, lucid, assetRef, priceOracleRef, interestOracleRef, collectorRef, govRef, treasuryRef) {
|
|
104
|
+
// Find Pkh, Skh
|
|
105
|
+
const [pkh, skh] = await addrDetails(lucid);
|
|
106
|
+
const now = Date.now();
|
|
107
|
+
// Fail if no pkh
|
|
108
|
+
if (!pkh)
|
|
109
|
+
return Promise.reject('Unable to determine the pub key hash of the wallet');
|
|
110
|
+
// Find Outputs: iAsset Output, CDP Output, Gov Output
|
|
111
|
+
const cdp = (await lucid.utxosByOutRef([cdpRef]))[0];
|
|
112
|
+
if (!cdp.datum)
|
|
113
|
+
throw 'Unable to find CDP Datum';
|
|
114
|
+
const cdpDatum = CDPContract.decodeCdpDatum(cdp.datum);
|
|
115
|
+
if (cdpDatum.type !== 'CDP')
|
|
116
|
+
throw 'Invalid CDP Datum';
|
|
117
|
+
const iAsset = await (assetRef
|
|
118
|
+
? IAssetHelpers.findIAssetByRef(assetRef, params, lucid)
|
|
119
|
+
: IAssetHelpers.findIAssetByName(cdpDatum.asset, params, lucid));
|
|
120
|
+
const gov = govRef
|
|
121
|
+
? (await lucid.utxosByOutRef([govRef]))[0]
|
|
122
|
+
: await lucid.utxoByUnit(params.govParams.govNFT[0].unCurrencySymbol +
|
|
123
|
+
fromText(params.govParams.govNFT[1].unTokenName));
|
|
124
|
+
// const [iAsset, cdp, gov] = await lucid.utxosByOutRef([
|
|
125
|
+
// dIAssetTokenRef,
|
|
126
|
+
// dCDPTokenRef,
|
|
127
|
+
// dGovTokenRef,
|
|
128
|
+
// ]);
|
|
129
|
+
if (!gov.datum)
|
|
130
|
+
throw 'Unable to find Gov Datum';
|
|
131
|
+
const govData = GovContract.decodeGovDatum(gov.datum);
|
|
132
|
+
if (!govData)
|
|
133
|
+
throw 'No Governance datum found';
|
|
134
|
+
const cdpScriptRefUtxo = await CDPContract.scriptRef(params.scriptReferences, lucid);
|
|
135
|
+
const cdpAssets = Object.assign({}, cdp.assets);
|
|
136
|
+
cdpAssets['lovelace'] = cdp.assets['lovelace'] + collateralAmount;
|
|
137
|
+
const interestOracleAsset = iAsset.datum.interestOracle;
|
|
138
|
+
const interestOracleOut = interestOracleRef
|
|
139
|
+
? (await lucid.utxosByOutRef([interestOracleRef]))[0]
|
|
140
|
+
: await lucid.utxoByUnit(interestOracleAsset[0].unCurrencySymbol +
|
|
141
|
+
fromText(interestOracleAsset[1].unTokenName));
|
|
142
|
+
if (!interestOracleOut.datum)
|
|
143
|
+
return Promise.reject('Interest Oracle datum not found');
|
|
144
|
+
const interestOracleDatum = InterestOracleContract.decodeInterestOracleDatum(interestOracleOut.datum);
|
|
145
|
+
let tx = lucid
|
|
146
|
+
.newTx()
|
|
147
|
+
.collectFrom([cdp], Data.to(new Constr(0, [BigInt(now), mintAmount, collateralAmount])))
|
|
148
|
+
.readFrom([iAsset.utxo, gov, cdpScriptRefUtxo])
|
|
149
|
+
.addSignerKey(pkh.hash);
|
|
150
|
+
if (!cdp.datum)
|
|
151
|
+
throw 'Unable to find CDP Datum';
|
|
152
|
+
let cdpD = CDPContract.decodeCdpDatum(cdp.datum);
|
|
153
|
+
if (!cdpD || cdpD.type !== 'CDP')
|
|
154
|
+
throw 'Invalid CDP Datum';
|
|
155
|
+
if (cdpD.fees.type !== 'ActiveCDPInterestTracking')
|
|
156
|
+
throw 'Invalid CDP Fees';
|
|
157
|
+
const newSnapshot = InterestOracleContract.calculateUnitaryInterestSinceOracleLastUpdated(BigInt(now), interestOracleDatum) + interestOracleDatum.unitaryInterest;
|
|
158
|
+
const cdpD_ = {
|
|
159
|
+
...cdpD,
|
|
160
|
+
mintedAmount: cdpD.mintedAmount + mintAmount,
|
|
161
|
+
fees: {
|
|
162
|
+
type: 'ActiveCDPInterestTracking',
|
|
163
|
+
last_settled: BigInt(now),
|
|
164
|
+
unitary_interest_snapshot: newSnapshot
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
tx.pay.ToContract(cdp.address, {
|
|
168
|
+
kind: 'inline',
|
|
169
|
+
value: CDPContract.encodeCdpDatum(cdpD_),
|
|
170
|
+
}, cdpAssets);
|
|
171
|
+
// Find Oracle Ref Input
|
|
172
|
+
const oracleAsset = iAsset.datum.price;
|
|
173
|
+
const oracleRefInput = priceOracleRef
|
|
174
|
+
? (await lucid.utxosByOutRef([priceOracleRef]))[0]
|
|
175
|
+
: await lucid.utxoByUnit(oracleAsset[0].unCurrencySymbol +
|
|
176
|
+
fromText(oracleAsset[1].unTokenName));
|
|
177
|
+
// Fail if delisted asset
|
|
178
|
+
if (!oracleRefInput.datum)
|
|
179
|
+
return Promise.reject('Invalid oracle input');
|
|
180
|
+
const od = PriceOracleContract.decodePriceOracleDatum(oracleRefInput.datum);
|
|
181
|
+
if (!od)
|
|
182
|
+
return Promise.reject('Invalid oracle input');
|
|
183
|
+
// TODO: Sanity check: oacle expiration
|
|
184
|
+
// Oracle timestamp - 20s (length of a slot)
|
|
185
|
+
// Oracle timestamp - 20s (length of a slot)
|
|
186
|
+
const cappedValidateTo = od.expiration - 20001n;
|
|
187
|
+
const timeValidFrom = now - 1_000;
|
|
188
|
+
const timeValidTo_ = now + params.cdpCreatorParams.biasTime - 1_000;
|
|
189
|
+
const timeValidTo = cappedValidateTo <= timeValidFrom
|
|
190
|
+
? timeValidTo_
|
|
191
|
+
: Math.min(timeValidTo_, Number(cappedValidateTo));
|
|
192
|
+
tx
|
|
193
|
+
.readFrom([oracleRefInput])
|
|
194
|
+
.validFrom(Number(timeValidFrom))
|
|
195
|
+
.validTo(Number(timeValidTo));
|
|
196
|
+
let fee = 0n;
|
|
197
|
+
if (collateralAmount < 0) {
|
|
198
|
+
fee += calculateFeeFromPercentage(govData.protocolParams.collateralFeePercentage, collateralAmount);
|
|
199
|
+
}
|
|
200
|
+
if (mintAmount > 0) {
|
|
201
|
+
fee += calculateFeeFromPercentage(iAsset.datum.debtMintingFeePercentage.getOnChainInt, mintAmount * od.price);
|
|
202
|
+
}
|
|
203
|
+
// Interest payment
|
|
204
|
+
const interestPaymentAsset = InterestOracleContract.calculateAccruedInterest(BigInt(now), cdpD.fees.unitary_interest_snapshot, cdpD.mintedAmount, cdpD.fees.last_settled, interestOracleDatum);
|
|
205
|
+
const interestPayment = (interestPaymentAsset * od.price) / 1000000n;
|
|
206
|
+
const interestCollectorPayment = calculateFeeFromPercentage(iAsset.datum.interestCollectorPortionPercentage.getOnChainInt, interestPayment);
|
|
207
|
+
const interestTreasuryPayment = interestPayment - interestCollectorPayment;
|
|
208
|
+
console.log(interestPayment, interestCollectorPayment, interestTreasuryPayment);
|
|
209
|
+
if (interestTreasuryPayment > 0) {
|
|
210
|
+
await TreasuryContract.feeTx(interestTreasuryPayment, lucid, params, tx, treasuryRef);
|
|
211
|
+
}
|
|
212
|
+
fee += interestCollectorPayment;
|
|
213
|
+
tx.readFrom([interestOracleOut]);
|
|
214
|
+
if (mintAmount !== 0n) {
|
|
215
|
+
const iAssetTokenScriptRefUtxo = await CDPContract.assetTokenRef(params.scriptReferences, lucid);
|
|
216
|
+
const iassetToken = params.cdpParams.cdpAssetSymbol.unCurrencySymbol + fromText(cdpD.asset);
|
|
217
|
+
const mintValue = {};
|
|
218
|
+
mintValue[iassetToken] = mintAmount;
|
|
219
|
+
tx.readFrom([iAssetTokenScriptRefUtxo]).mintAssets(mintValue, Data.to(new Constr(0, [])));
|
|
220
|
+
}
|
|
221
|
+
if (fee > 0n) {
|
|
222
|
+
await CollectorContract.feeTx(fee, lucid, params, tx, collectorRef);
|
|
223
|
+
}
|
|
224
|
+
return tx;
|
|
225
|
+
}
|
|
226
|
+
static async close(cdpRef, params, lucid, assetRef, priceOracleRef, interestOracleRef, collectorRef, govRef, treasuryRef) {
|
|
227
|
+
// Find Pkh, Skh
|
|
228
|
+
const [pkh, skh] = await addrDetails(lucid);
|
|
229
|
+
const now = Date.now();
|
|
230
|
+
// Fail if no pkh
|
|
231
|
+
if (!pkh)
|
|
232
|
+
return Promise.reject('Unable to determine the pub key hash of the wallet');
|
|
233
|
+
// Find Outputs: iAsset Output, CDP Output, Gov Output
|
|
234
|
+
const cdp = (await lucid.utxosByOutRef([cdpRef]))[0];
|
|
235
|
+
if (!cdp.datum)
|
|
236
|
+
throw 'Unable to find CDP Datum';
|
|
237
|
+
const cdpDatum = CDPContract.decodeCdpDatum(cdp.datum);
|
|
238
|
+
if (cdpDatum.type !== 'CDP')
|
|
239
|
+
throw 'Invalid CDP Datum';
|
|
240
|
+
const iAsset = await (assetRef
|
|
241
|
+
? IAssetHelpers.findIAssetByRef(assetRef, params, lucid)
|
|
242
|
+
: IAssetHelpers.findIAssetByName(cdpDatum.asset, params, lucid));
|
|
243
|
+
const gov = govRef
|
|
244
|
+
? (await lucid.utxosByOutRef([govRef]))[0]
|
|
245
|
+
: await lucid.utxoByUnit(params.govParams.govNFT[0].unCurrencySymbol +
|
|
246
|
+
fromText(params.govParams.govNFT[1].unTokenName));
|
|
247
|
+
if (!gov.datum)
|
|
248
|
+
throw 'Unable to find Gov Datum';
|
|
249
|
+
const govData = GovContract.decodeGovDatum(gov.datum);
|
|
250
|
+
if (!govData)
|
|
251
|
+
throw 'No Governance datum found';
|
|
252
|
+
const cdpScriptRefUtxo = await CDPContract.scriptRef(params.scriptReferences, lucid);
|
|
253
|
+
const interestOracleAsset = iAsset.datum.interestOracle;
|
|
254
|
+
const interestOracleOut = interestOracleRef
|
|
255
|
+
? (await lucid.utxosByOutRef([interestOracleRef]))[0]
|
|
256
|
+
: await lucid.utxoByUnit(interestOracleAsset[0].unCurrencySymbol +
|
|
257
|
+
fromText(interestOracleAsset[1].unTokenName));
|
|
258
|
+
if (!interestOracleOut.datum)
|
|
259
|
+
return Promise.reject('Interest Oracle datum not found');
|
|
260
|
+
const interestOracleDatum = InterestOracleContract.decodeInterestOracleDatum(interestOracleOut.datum);
|
|
261
|
+
let tx = lucid
|
|
262
|
+
.newTx()
|
|
263
|
+
.collectFrom([cdp], Data.to(new Constr(1, [BigInt(now)])))
|
|
264
|
+
.readFrom([iAsset.utxo, gov, cdpScriptRefUtxo])
|
|
265
|
+
.addSignerKey(pkh.hash);
|
|
266
|
+
if (!cdp.datum)
|
|
267
|
+
throw 'Unable to find CDP Datum';
|
|
268
|
+
let cdpD = CDPContract.decodeCdpDatum(cdp.datum);
|
|
269
|
+
if (!cdpD || cdpD.type !== 'CDP')
|
|
270
|
+
throw 'Invalid CDP Datum';
|
|
271
|
+
if (cdpD.fees.type !== 'ActiveCDPInterestTracking')
|
|
272
|
+
throw 'Invalid CDP Fees';
|
|
273
|
+
// Find Oracle Ref Input
|
|
274
|
+
const oracleAsset = iAsset.datum.price;
|
|
275
|
+
const oracleRefInput = priceOracleRef
|
|
276
|
+
? (await lucid.utxosByOutRef([priceOracleRef]))[0]
|
|
277
|
+
: await lucid.utxoByUnit(oracleAsset[0].unCurrencySymbol +
|
|
278
|
+
fromText(oracleAsset[1].unTokenName));
|
|
279
|
+
// Fail if delisted asset
|
|
280
|
+
if (!oracleRefInput.datum)
|
|
281
|
+
return Promise.reject('Invalid oracle input');
|
|
282
|
+
const od = PriceOracleContract.decodePriceOracleDatum(oracleRefInput.datum);
|
|
283
|
+
if (!od)
|
|
284
|
+
return Promise.reject('Invalid oracle input');
|
|
285
|
+
// TODO: Sanity check: oacle expiration
|
|
286
|
+
// Oracle timestamp - 20s (length of a slot)
|
|
287
|
+
// Oracle timestamp - 20s (length of a slot)
|
|
288
|
+
const cappedValidateTo = od.expiration - 20001n;
|
|
289
|
+
const timeValidFrom = now - 1_000;
|
|
290
|
+
const timeValidTo_ = now + params.cdpCreatorParams.biasTime - 1_000;
|
|
291
|
+
const timeValidTo = cappedValidateTo <= timeValidFrom
|
|
292
|
+
? timeValidTo_
|
|
293
|
+
: Math.min(timeValidTo_, Number(cappedValidateTo));
|
|
294
|
+
tx
|
|
295
|
+
.readFrom([oracleRefInput])
|
|
296
|
+
.validFrom(Number(timeValidFrom))
|
|
297
|
+
.validTo(Number(timeValidTo));
|
|
298
|
+
let fee = 0n;
|
|
299
|
+
// Interest payment
|
|
300
|
+
const interestPaymentAsset = InterestOracleContract.calculateAccruedInterest(BigInt(now), cdpD.fees.unitary_interest_snapshot, cdpD.mintedAmount, cdpD.fees.last_settled, interestOracleDatum);
|
|
301
|
+
const interestPayment = (interestPaymentAsset * od.price) / 1000000n;
|
|
302
|
+
const interestCollectorPayment = calculateFeeFromPercentage(iAsset.datum.interestCollectorPortionPercentage.getOnChainInt, interestPayment);
|
|
303
|
+
const interestTreasuryPayment = interestPayment - interestCollectorPayment;
|
|
304
|
+
console.log(interestPayment, interestCollectorPayment, interestTreasuryPayment);
|
|
305
|
+
if (interestTreasuryPayment > 0) {
|
|
306
|
+
await TreasuryContract.feeTx(interestTreasuryPayment, lucid, params, tx, treasuryRef);
|
|
307
|
+
}
|
|
308
|
+
fee += interestCollectorPayment;
|
|
309
|
+
tx.readFrom([interestOracleOut]);
|
|
310
|
+
const iAssetTokenScriptRefUtxo = await CDPContract.assetTokenRef(params.scriptReferences, lucid);
|
|
311
|
+
const iassetToken = params.cdpParams.cdpAssetSymbol.unCurrencySymbol + fromText(cdpD.asset);
|
|
312
|
+
const assetBurnValue = {};
|
|
313
|
+
assetBurnValue[iassetToken] = -BigInt(cdpD.mintedAmount);
|
|
314
|
+
const cdpTokenBurnValue = {};
|
|
315
|
+
cdpTokenBurnValue[params.cdpParams.cdpAuthToken[0].unCurrencySymbol + fromText(params.cdpParams.cdpAuthToken[1].unTokenName)] = -1n;
|
|
316
|
+
const cdpAuthTokenScriptRefUtxo = await CDPContract.cdpAuthTokenRef(params.scriptReferences, lucid);
|
|
317
|
+
tx.readFrom([iAssetTokenScriptRefUtxo]).mintAssets(assetBurnValue, Data.to(new Constr(0, []))).readFrom([cdpAuthTokenScriptRefUtxo]).mintAssets(cdpTokenBurnValue, Data.to(new Constr(0, [])));
|
|
318
|
+
if (fee > 0n) {
|
|
319
|
+
await CollectorContract.feeTx(fee, lucid, params, tx, collectorRef);
|
|
320
|
+
}
|
|
321
|
+
return tx;
|
|
322
|
+
}
|
|
323
|
+
static decodeCdpDatum(datum) {
|
|
324
|
+
const cdpDatum = Data.from(datum);
|
|
325
|
+
if (cdpDatum.index == 1 && cdpDatum.fields[0].index == 0) {
|
|
326
|
+
const iasset = cdpDatum.fields[0].fields;
|
|
327
|
+
return {
|
|
328
|
+
type: 'IAsset',
|
|
329
|
+
name: toText(iasset[0]),
|
|
330
|
+
price: iasset[1].index === 0
|
|
331
|
+
? { getOnChainInt: iasset[1].fields[0] }
|
|
332
|
+
: [
|
|
333
|
+
{ unCurrencySymbol: iasset[1].fields[0].fields[0].fields[0] },
|
|
334
|
+
{
|
|
335
|
+
unTokenName: toText(iasset[1].fields[0].fields[0].fields[1]),
|
|
336
|
+
},
|
|
337
|
+
],
|
|
338
|
+
interestOracle: [
|
|
339
|
+
{ unCurrencySymbol: iasset[2].fields[0] },
|
|
340
|
+
{ unTokenName: toText(iasset[2].fields[1]) },
|
|
341
|
+
],
|
|
342
|
+
redemptionRatioPercentage: { getOnChainInt: iasset[3].fields[0] },
|
|
343
|
+
maintenanceRatioPercentage: { getOnChainInt: iasset[4].fields[0] },
|
|
344
|
+
liquidationRatioPercentage: { getOnChainInt: iasset[5].fields[0] },
|
|
345
|
+
debtMintingFeePercentage: { getOnChainInt: iasset[6].fields[0] },
|
|
346
|
+
liquidationProcessingFeePercentage: {
|
|
347
|
+
getOnChainInt: iasset[7].fields[0],
|
|
348
|
+
},
|
|
349
|
+
stabilityPoolWithdrawalFeePercentage: {
|
|
350
|
+
getOnChainInt: iasset[8].fields[0],
|
|
351
|
+
},
|
|
352
|
+
redemptionReimbursementPercentage: {
|
|
353
|
+
getOnChainInt: iasset[9].fields[0],
|
|
354
|
+
},
|
|
355
|
+
redemptionProcessingFeePercentage: {
|
|
356
|
+
getOnChainInt: iasset[10].fields[0],
|
|
357
|
+
},
|
|
358
|
+
interestCollectorPortionPercentage: {
|
|
359
|
+
getOnChainInt: iasset[11].fields[0],
|
|
360
|
+
},
|
|
361
|
+
firstAsset: iasset[12].index === 1,
|
|
362
|
+
nextAsset: iasset[13].index === 0 ? toText(iasset[13].fields[0]) : undefined,
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
else if (cdpDatum.index == 0 && cdpDatum.fields[0].index == 0) {
|
|
366
|
+
const cdp = cdpDatum.fields[0].fields;
|
|
367
|
+
return {
|
|
368
|
+
type: 'CDP',
|
|
369
|
+
owner: cdp[0].fields[0],
|
|
370
|
+
asset: toText(cdp[1]),
|
|
371
|
+
mintedAmount: cdp[2],
|
|
372
|
+
fees: cdp[3].index === 0
|
|
373
|
+
? {
|
|
374
|
+
type: 'ActiveCDPInterestTracking',
|
|
375
|
+
last_settled: cdp[3].fields[0],
|
|
376
|
+
unitary_interest_snapshot: cdp[3].fields[1],
|
|
377
|
+
}
|
|
378
|
+
: {
|
|
379
|
+
type: 'FrozenCDPAccumulatedFees',
|
|
380
|
+
lovelaces_treasury: cdp[3].fields[0],
|
|
381
|
+
lovelaces_indy_stakers: cdp[3].fields[1],
|
|
382
|
+
},
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
throw 'Invalid CDP Datum provided';
|
|
386
|
+
}
|
|
387
|
+
static encodeCdpDatum(datum) {
|
|
388
|
+
if (datum.type === 'CDP') {
|
|
389
|
+
return Data.to(new Constr(0, [
|
|
390
|
+
new Constr(0, [
|
|
391
|
+
datum.owner ? new Constr(0, [datum.owner]) : new Constr(1, []),
|
|
392
|
+
fromText(datum.asset),
|
|
393
|
+
BigInt(datum.mintedAmount),
|
|
394
|
+
datum.fees.type === 'ActiveCDPInterestTracking'
|
|
395
|
+
? new Constr(0, [
|
|
396
|
+
datum.fees.last_settled,
|
|
397
|
+
datum.fees.unitary_interest_snapshot,
|
|
398
|
+
])
|
|
399
|
+
: new Constr(1, [
|
|
400
|
+
datum.fees.lovelaces_treasury,
|
|
401
|
+
datum.fees.lovelaces_indy_stakers,
|
|
402
|
+
]),
|
|
403
|
+
]),
|
|
404
|
+
]));
|
|
405
|
+
}
|
|
406
|
+
else if (datum.type === 'IAsset') {
|
|
407
|
+
return Data.to(new Constr(1, [
|
|
408
|
+
new Constr(0, [
|
|
409
|
+
fromText(datum.name),
|
|
410
|
+
'getOnChainInt' in datum.price
|
|
411
|
+
? new Constr(0, [
|
|
412
|
+
new Constr(0, [BigInt(datum.price.getOnChainInt)]),
|
|
413
|
+
])
|
|
414
|
+
: new Constr(1, [
|
|
415
|
+
new Constr(0, [
|
|
416
|
+
new Constr(0, [
|
|
417
|
+
datum.price[0].unCurrencySymbol,
|
|
418
|
+
fromText(datum.price[1].unTokenName),
|
|
419
|
+
]),
|
|
420
|
+
]),
|
|
421
|
+
]),
|
|
422
|
+
new Constr(0, [
|
|
423
|
+
datum.interestOracle[0].unCurrencySymbol,
|
|
424
|
+
fromText(datum.interestOracle[1].unTokenName),
|
|
425
|
+
]),
|
|
426
|
+
new Constr(0, [
|
|
427
|
+
BigInt(datum.redemptionRatioPercentage.getOnChainInt),
|
|
428
|
+
]),
|
|
429
|
+
new Constr(0, [
|
|
430
|
+
BigInt(datum.maintenanceRatioPercentage.getOnChainInt),
|
|
431
|
+
]),
|
|
432
|
+
new Constr(0, [
|
|
433
|
+
BigInt(datum.liquidationRatioPercentage.getOnChainInt),
|
|
434
|
+
]),
|
|
435
|
+
new Constr(0, [
|
|
436
|
+
BigInt(datum.debtMintingFeePercentage.getOnChainInt),
|
|
437
|
+
]),
|
|
438
|
+
new Constr(0, [
|
|
439
|
+
BigInt(datum.liquidationProcessingFeePercentage.getOnChainInt),
|
|
440
|
+
]),
|
|
441
|
+
new Constr(0, [
|
|
442
|
+
BigInt(datum.stabilityPoolWithdrawalFeePercentage.getOnChainInt),
|
|
443
|
+
]),
|
|
444
|
+
new Constr(0, [
|
|
445
|
+
BigInt(datum.redemptionReimbursementPercentage.getOnChainInt),
|
|
446
|
+
]),
|
|
447
|
+
new Constr(0, [
|
|
448
|
+
BigInt(datum.redemptionProcessingFeePercentage.getOnChainInt),
|
|
449
|
+
]),
|
|
450
|
+
new Constr(0, [
|
|
451
|
+
BigInt(datum.interestCollectorPortionPercentage.getOnChainInt),
|
|
452
|
+
]),
|
|
453
|
+
datum.firstAsset ? new Constr(1, []) : new Constr(0, []),
|
|
454
|
+
datum.nextAsset
|
|
455
|
+
? new Constr(0, [fromText(datum.nextAsset)])
|
|
456
|
+
: new Constr(1, []),
|
|
457
|
+
]),
|
|
458
|
+
]));
|
|
459
|
+
}
|
|
460
|
+
throw 'Invalid CDP Datum provided';
|
|
461
|
+
}
|
|
462
|
+
static datum(hash, asset, mintedAmount, fees) {
|
|
463
|
+
return new Constr(0, [
|
|
464
|
+
new Constr(0, [
|
|
465
|
+
new Constr(0, [hash.hash]),
|
|
466
|
+
fromText(asset),
|
|
467
|
+
BigInt(mintedAmount),
|
|
468
|
+
fees.type === 'ActiveCDPInterestTracking'
|
|
469
|
+
? new Constr(0, [
|
|
470
|
+
BigInt(fees.last_settled),
|
|
471
|
+
BigInt(fees.unitary_interest_snapshot),
|
|
472
|
+
])
|
|
473
|
+
: new Constr(0, [
|
|
474
|
+
BigInt(fees.lovelaces_treasury),
|
|
475
|
+
BigInt(fees.lovelaces_indy_stakers),
|
|
476
|
+
]),
|
|
477
|
+
]),
|
|
478
|
+
]);
|
|
479
|
+
}
|
|
480
|
+
static validator(params) {
|
|
481
|
+
return {
|
|
482
|
+
type: _cdpValidator.type,
|
|
483
|
+
script: applyParamsToScript(_cdpValidator.cborHex, [
|
|
484
|
+
new Constr(0, [
|
|
485
|
+
new Constr(0, [
|
|
486
|
+
params.cdpAuthToken[0].unCurrencySymbol,
|
|
487
|
+
fromText(params.cdpAuthToken[1].unTokenName),
|
|
488
|
+
]),
|
|
489
|
+
params.cdpAssetSymbol.unCurrencySymbol,
|
|
490
|
+
new Constr(0, [
|
|
491
|
+
params.iAssetAuthToken[0].unCurrencySymbol,
|
|
492
|
+
fromText(params.iAssetAuthToken[1].unTokenName),
|
|
493
|
+
]),
|
|
494
|
+
new Constr(0, [
|
|
495
|
+
params.stabilityPoolAuthToken[0].unCurrencySymbol,
|
|
496
|
+
fromText(params.stabilityPoolAuthToken[1].unTokenName),
|
|
497
|
+
]),
|
|
498
|
+
new Constr(0, [
|
|
499
|
+
params.versionRecordToken[0].unCurrencySymbol,
|
|
500
|
+
fromText(params.versionRecordToken[1].unTokenName),
|
|
501
|
+
]),
|
|
502
|
+
new Constr(0, [
|
|
503
|
+
params.upgradeToken[0].unCurrencySymbol,
|
|
504
|
+
fromText(params.upgradeToken[1].unTokenName),
|
|
505
|
+
]),
|
|
506
|
+
params.collectorValHash,
|
|
507
|
+
params.spValHash,
|
|
508
|
+
new Constr(0, [
|
|
509
|
+
params.govNFT[0].unCurrencySymbol,
|
|
510
|
+
fromText(params.govNFT[1].unTokenName),
|
|
511
|
+
]),
|
|
512
|
+
BigInt(params.minCollateralInLovelace),
|
|
513
|
+
BigInt(params.partialRedemptionExtraFeeLovelace),
|
|
514
|
+
BigInt(params.biasTime),
|
|
515
|
+
params.treasuryValHash,
|
|
516
|
+
]),
|
|
517
|
+
]),
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
static validatorHash(params) {
|
|
521
|
+
return validatorToScriptHash(CDPContract.validator(params));
|
|
522
|
+
}
|
|
523
|
+
static address(cdpParams, lucid, skh) {
|
|
524
|
+
const network = lucid.config().network;
|
|
525
|
+
if (!network) {
|
|
526
|
+
throw new Error('Network configuration is undefined');
|
|
527
|
+
}
|
|
528
|
+
return validatorToAddress(network, CDPContract.validator(cdpParams), skh);
|
|
529
|
+
}
|
|
530
|
+
static scriptRef(params, lucid) {
|
|
531
|
+
return scriptRef(params.cdpValidatorRef, lucid);
|
|
532
|
+
}
|
|
533
|
+
static cdpAuthTokenRef(params, lucid) {
|
|
534
|
+
return scriptRef(params.authTokenPolicies.cdpAuthTokenRef, lucid);
|
|
535
|
+
}
|
|
536
|
+
static assetTokenRef(params, lucid) {
|
|
537
|
+
return scriptRef(params.iAssetTokenPolicyRef, lucid);
|
|
538
|
+
}
|
|
539
|
+
static assetAuthTokenRef(params, lucid) {
|
|
540
|
+
return scriptRef(params.authTokenPolicies.iAssetTokenRef, lucid);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Address, LucidEvolution, OutRef, SpendingValidator, TxBuilder, UTxO } from '@lucid-evolution/lucid';
|
|
2
|
+
import { CollectorParams, ScriptReferences, SystemParams } from '../types/system-params';
|
|
3
|
+
export declare class CollectorContract {
|
|
4
|
+
static feeTx(fee: bigint, lucid: LucidEvolution, params: SystemParams, tx: TxBuilder, collectorRef?: OutRef): Promise<void>;
|
|
5
|
+
static validator(params: CollectorParams): SpendingValidator;
|
|
6
|
+
static validatorHash(params: CollectorParams): string;
|
|
7
|
+
static address(params: CollectorParams, lucid: LucidEvolution): Address;
|
|
8
|
+
static scriptRef(params: ScriptReferences, lucid: LucidEvolution): Promise<UTxO>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { applyParamsToScript, Constr, Data, fromText, validatorToAddress, validatorToScriptHash, } from '@lucid-evolution/lucid';
|
|
2
|
+
import { _collectorValidator } from '../scripts/collector-validator';
|
|
3
|
+
import { getRandomElement, scriptRef } from '../helpers/lucid-utils';
|
|
4
|
+
export class CollectorContract {
|
|
5
|
+
static async feeTx(fee, lucid, params, tx, collectorRef) {
|
|
6
|
+
const collectorUtxo = collectorRef
|
|
7
|
+
? getRandomElement(await lucid.utxosByOutRef([collectorRef]))
|
|
8
|
+
: getRandomElement(await lucid.utxosAt(CollectorContract.address(params.collectorParams, lucid)));
|
|
9
|
+
const collectorScriptRefUtxo = await CollectorContract.scriptRef(params.scriptReferences, lucid);
|
|
10
|
+
tx.collectFrom([collectorUtxo], Data.to(new Constr(0, [])))
|
|
11
|
+
.pay.ToContract(collectorUtxo.address, { kind: 'inline', value: Data.to(new Constr(0, [])) }, {
|
|
12
|
+
...collectorUtxo.assets,
|
|
13
|
+
lovelace: collectorUtxo.assets['lovelace'] + fee,
|
|
14
|
+
})
|
|
15
|
+
.readFrom([collectorScriptRefUtxo]);
|
|
16
|
+
}
|
|
17
|
+
// Collector Validator
|
|
18
|
+
static validator(params) {
|
|
19
|
+
return {
|
|
20
|
+
type: 'PlutusV2',
|
|
21
|
+
script: applyParamsToScript(_collectorValidator.cborHex, [
|
|
22
|
+
new Constr(0, [
|
|
23
|
+
new Constr(0, [
|
|
24
|
+
params.stakingManagerNFT[0].unCurrencySymbol,
|
|
25
|
+
fromText(params.stakingManagerNFT[1].unTokenName),
|
|
26
|
+
]),
|
|
27
|
+
new Constr(0, [
|
|
28
|
+
params.stakingToken[0].unCurrencySymbol,
|
|
29
|
+
fromText(params.stakingToken[1].unTokenName),
|
|
30
|
+
]),
|
|
31
|
+
new Constr(0, [
|
|
32
|
+
params.versionRecordToken[0].unCurrencySymbol,
|
|
33
|
+
fromText(params.versionRecordToken[1].unTokenName),
|
|
34
|
+
]),
|
|
35
|
+
]),
|
|
36
|
+
]),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
static validatorHash(params) {
|
|
40
|
+
return validatorToScriptHash(CollectorContract.validator(params));
|
|
41
|
+
}
|
|
42
|
+
static address(params, lucid) {
|
|
43
|
+
const network = lucid.config().network;
|
|
44
|
+
if (!network) {
|
|
45
|
+
throw new Error('Network configuration is undefined');
|
|
46
|
+
}
|
|
47
|
+
return validatorToAddress(network, CollectorContract.validator(params));
|
|
48
|
+
}
|
|
49
|
+
static async scriptRef(params, lucid) {
|
|
50
|
+
return scriptRef(params.collectorValidatorRef, lucid);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Constr, Data } from '@lucid-evolution/lucid';
|
|
2
|
+
export class GovContract {
|
|
3
|
+
static decodeGovDatum(datum) {
|
|
4
|
+
const d = Data.from(datum);
|
|
5
|
+
if (d.index !== 0 ||
|
|
6
|
+
d.fields.length !== 6 ||
|
|
7
|
+
d.fields[1].fields.length !== 10)
|
|
8
|
+
throw 'Invalid GovDatum found';
|
|
9
|
+
return {
|
|
10
|
+
currentProposal: d.fields[0],
|
|
11
|
+
protocolParams: {
|
|
12
|
+
proposalDeposit: d.fields[1].fields[0],
|
|
13
|
+
votingPeriod: d.fields[1].fields[1],
|
|
14
|
+
effectiveDelay: d.fields[1].fields[2],
|
|
15
|
+
expirationPeriod: d.fields[1].fields[3],
|
|
16
|
+
collateralFeePercentage: d.fields[1].fields[4].fields[0],
|
|
17
|
+
proposingPeriod: d.fields[1].fields[5],
|
|
18
|
+
totalShards: d.fields[1].fields[6],
|
|
19
|
+
minimumQuorum: d.fields[1].fields[7],
|
|
20
|
+
maxTreasuryLovelaceSpend: d.fields[1].fields[8],
|
|
21
|
+
maxTreasuryIndySpend: d.fields[1].fields[9],
|
|
22
|
+
},
|
|
23
|
+
currentVersion: d.fields[2],
|
|
24
|
+
iassetsCount: d.fields[3],
|
|
25
|
+
activeProposals: d.fields[4],
|
|
26
|
+
treasuryIndyWithdrawnAmt: d.fields[5],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
static encodeGovDatum(datum) {
|
|
30
|
+
return Data.to(new Constr(0, [
|
|
31
|
+
datum.currentProposal,
|
|
32
|
+
new Constr(0, [
|
|
33
|
+
datum.protocolParams.proposalDeposit,
|
|
34
|
+
datum.protocolParams.votingPeriod,
|
|
35
|
+
datum.protocolParams.effectiveDelay,
|
|
36
|
+
datum.protocolParams.expirationPeriod,
|
|
37
|
+
new Constr(0, [datum.protocolParams.collateralFeePercentage]),
|
|
38
|
+
datum.protocolParams.proposingPeriod,
|
|
39
|
+
datum.protocolParams.totalShards,
|
|
40
|
+
datum.protocolParams.minimumQuorum,
|
|
41
|
+
datum.protocolParams.maxTreasuryLovelaceSpend,
|
|
42
|
+
datum.protocolParams.maxTreasuryIndySpend,
|
|
43
|
+
]),
|
|
44
|
+
datum.currentVersion,
|
|
45
|
+
datum.iassetsCount,
|
|
46
|
+
datum.activeProposals,
|
|
47
|
+
datum.treasuryIndyWithdrawnAmt,
|
|
48
|
+
]));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { InterestOracleDatum } from "../types/indigo/interest-oracle";
|
|
2
|
+
export declare class InterestOracleContract {
|
|
3
|
+
static decodeInterestOracleDatum(datum: string): InterestOracleDatum;
|
|
4
|
+
static encodeInterestOracleDatum(datum: InterestOracleDatum): string;
|
|
5
|
+
static calculateUnitaryInterestSinceOracleLastUpdated(now: bigint, oracleDatum: InterestOracleDatum): bigint;
|
|
6
|
+
static calculateUnitaryInterest(timePeriod: bigint, interestRate: bigint): bigint;
|
|
7
|
+
static calculateAccruedInterest(now: bigint, unitaryInterestSnapshot: bigint, mintedAmount: bigint, interestLastSettled: bigint, interestOracleDatum: InterestOracleDatum): bigint;
|
|
8
|
+
}
|