@indigo-labs/indigo-sdk 0.2.41 → 0.3.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.
Files changed (201) hide show
  1. package/.github/workflows/ci.yml +4 -2
  2. package/dist/index.d.mts +3008 -2194
  3. package/dist/index.d.ts +3008 -2194
  4. package/dist/index.js +9827 -6194
  5. package/dist/index.mjs +8591 -4809
  6. package/package.json +14 -3
  7. package/src/contracts/cdp/helpers.ts +68 -72
  8. package/src/contracts/cdp/scripts.ts +50 -13
  9. package/src/contracts/cdp/transactions.ts +831 -545
  10. package/src/contracts/cdp/types-new.ts +256 -0
  11. package/src/contracts/cdp/types.ts +26 -144
  12. package/src/contracts/cdp-creator/scripts.ts +15 -9
  13. package/src/contracts/cdp-creator/types-new.ts +50 -0
  14. package/src/contracts/cdp-creator/types.ts +5 -31
  15. package/src/contracts/collector/scripts.ts +1 -1
  16. package/src/contracts/collector/transactions.ts +23 -13
  17. package/src/contracts/collector/types-new.ts +17 -0
  18. package/src/contracts/execute/scripts.ts +19 -10
  19. package/src/contracts/execute/types-new.ts +44 -0
  20. package/src/contracts/execute/types.ts +5 -38
  21. package/src/contracts/gov/helpers.ts +187 -51
  22. package/src/contracts/gov/scripts.ts +17 -10
  23. package/src/contracts/gov/transactions.ts +599 -271
  24. package/src/contracts/gov/types-new.ts +253 -100
  25. package/src/contracts/gov/types.ts +4 -71
  26. package/src/contracts/iasset/helpers.ts +172 -0
  27. package/src/contracts/iasset/scripts.ts +38 -0
  28. package/src/contracts/iasset/types.ts +154 -0
  29. package/src/contracts/initialize/actions.ts +768 -0
  30. package/src/contracts/initialize/helpers.ts +611 -36
  31. package/src/contracts/initialize/types.ts +102 -28
  32. package/src/contracts/interest-collection/helpers.ts +19 -0
  33. package/src/contracts/interest-collection/scripts.ts +44 -0
  34. package/src/contracts/interest-collection/transactions.ts +436 -0
  35. package/src/contracts/interest-collection/types-new.ts +50 -0
  36. package/src/contracts/interest-collection/types.ts +26 -0
  37. package/src/contracts/interest-oracle/helpers.ts +2 -30
  38. package/src/contracts/interest-oracle/scripts.ts +1 -1
  39. package/src/contracts/interest-oracle/transactions.ts +21 -16
  40. package/src/contracts/interest-oracle/types-new.ts +32 -0
  41. package/src/contracts/interest-oracle/types.ts +1 -40
  42. package/src/contracts/one-shot/transactions.ts +1 -2
  43. package/src/contracts/poll/helpers.ts +5 -23
  44. package/src/contracts/poll/scripts.ts +12 -13
  45. package/src/contracts/poll/types-poll-manager.ts +1 -19
  46. package/src/contracts/poll/types-poll-new.ts +170 -0
  47. package/src/contracts/poll/types-poll-shard.ts +2 -24
  48. package/src/contracts/price-oracle/helpers.ts +1 -4
  49. package/src/contracts/price-oracle/scripts.ts +3 -8
  50. package/src/contracts/price-oracle/transactions.ts +32 -25
  51. package/src/contracts/price-oracle/types-new.ts +50 -0
  52. package/src/contracts/price-oracle/types.ts +2 -36
  53. package/src/contracts/pyth-feed/helpers.ts +58 -0
  54. package/src/contracts/pyth-feed/scripts.ts +15 -0
  55. package/src/contracts/pyth-feed/types.ts +181 -0
  56. package/src/contracts/rob/helpers.ts +405 -0
  57. package/src/contracts/rob/scripts.ts +35 -0
  58. package/src/contracts/rob/transactions.ts +410 -0
  59. package/src/contracts/rob/types-new.ts +128 -0
  60. package/src/contracts/rob/types.ts +16 -0
  61. package/src/contracts/rob-leverage/helpers.ts +424 -0
  62. package/src/contracts/{leverage → rob-leverage}/transactions.ts +68 -48
  63. package/src/contracts/stability-pool/helpers.ts +714 -230
  64. package/src/contracts/stability-pool/scripts.ts +20 -15
  65. package/src/contracts/stability-pool/transactions.ts +625 -495
  66. package/src/contracts/stability-pool/types-new.ts +237 -100
  67. package/src/contracts/stability-pool/types.ts +5 -22
  68. package/src/contracts/stableswap/helpers.ts +22 -0
  69. package/src/contracts/stableswap/scripts.ts +37 -0
  70. package/src/contracts/stableswap/transactions.ts +647 -0
  71. package/src/contracts/stableswap/types-new.ts +131 -0
  72. package/src/contracts/stableswap/types.ts +17 -0
  73. package/src/contracts/staking/helpers.ts +49 -34
  74. package/src/contracts/staking/scripts.ts +1 -1
  75. package/src/contracts/staking/transactions.ts +85 -130
  76. package/src/contracts/staking/types-new.ts +60 -28
  77. package/src/contracts/staking/types.ts +1 -28
  78. package/src/contracts/treasury/helpers.ts +21 -0
  79. package/src/contracts/treasury/scripts.ts +16 -26
  80. package/src/contracts/treasury/transactions.ts +256 -27
  81. package/src/contracts/treasury/types-new.ts +69 -0
  82. package/src/contracts/treasury/types.ts +2 -43
  83. package/src/contracts/version-registry/scripts.ts +2 -2
  84. package/src/contracts/version-registry/types-new.ts +6 -7
  85. package/src/index.ts +37 -20
  86. package/src/scripts/auth-token-policy.ts +3 -2
  87. package/src/scripts/iasset-policy.ts +3 -2
  88. package/src/types/evolution-schema-options.ts +3 -3
  89. package/src/types/generic.ts +17 -89
  90. package/src/types/multisig.ts +48 -0
  91. package/src/types/on-chain-decimal.ts +14 -7
  92. package/src/types/rational.ts +61 -0
  93. package/src/types/system-params.ts +237 -41
  94. package/src/utils/array-utils.ts +70 -1
  95. package/src/utils/bigint-utils.ts +12 -0
  96. package/src/utils/indigo-helpers.ts +8 -10
  97. package/src/utils/lucid-utils.ts +47 -40
  98. package/src/utils/oracle-helpers.ts +62 -0
  99. package/src/utils/pyth/decode.ts +223 -0
  100. package/src/utils/pyth/encode.ts +262 -0
  101. package/src/utils/pyth/index.ts +14 -0
  102. package/src/utils/pyth/types.ts +87 -0
  103. package/src/validators/always-succeed-validator.ts +6 -0
  104. package/src/validators/cdp-creator-validator.ts +2 -2
  105. package/src/validators/cdp-redeem-validator.ts +7 -0
  106. package/src/validators/cdp-validator.ts +2 -2
  107. package/src/validators/collector-validator.ts +2 -2
  108. package/src/validators/execute-validator.ts +2 -2
  109. package/src/validators/governance-validator.ts +2 -2
  110. package/src/validators/iasset-validator.ts +7 -0
  111. package/src/validators/interest-collection-validator.ts +7 -0
  112. package/src/validators/interest-oracle-validator.ts +2 -2
  113. package/src/validators/poll-manager-validator.ts +2 -2
  114. package/src/validators/poll-shard-validator.ts +2 -2
  115. package/src/validators/price-oracle-validator.ts +7 -0
  116. package/src/validators/pyth-feed-validator.ts +7 -0
  117. package/src/validators/rob-validator.ts +7 -0
  118. package/src/validators/stability-pool-validator.ts +2 -2
  119. package/src/validators/stableswap-validator.ts +7 -0
  120. package/src/validators/staking-validator.ts +2 -2
  121. package/src/validators/treasury-validator.ts +2 -2
  122. package/src/validators/version-record-policy.ts +2 -2
  123. package/src/validators/version-registry-validator.ts +2 -2
  124. package/tests/always-succeed/script.ts +7 -0
  125. package/tests/bigint-utils.test.ts +41 -0
  126. package/tests/cdp/actions.ts +611 -0
  127. package/tests/cdp/cdp-helpers.ts +55 -0
  128. package/tests/cdp/cdp-queries.ts +440 -0
  129. package/tests/cdp/cdp.test.ts +6087 -0
  130. package/tests/cdp/transactions-mutated.ts +1729 -0
  131. package/tests/data/system-params.json +177 -34
  132. package/tests/datums.test.ts +209 -210
  133. package/tests/endpoints/initialize.ts +68 -0
  134. package/tests/endpoints/interest-collector.ts +37 -0
  135. package/tests/endpoints/treasury.ts +70 -0
  136. package/tests/gov/actions.ts +406 -0
  137. package/tests/gov/gov.test.ts +4450 -0
  138. package/tests/{queries → gov}/governance-queries.ts +6 -3
  139. package/tests/hash-checks.test.ts +38 -11
  140. package/tests/indigo-test-helpers.ts +100 -0
  141. package/tests/initialize.test.ts +61 -9
  142. package/tests/interest-collection/interest-collection.test.ts +892 -0
  143. package/tests/interest-collection/interest-collector-queries.ts +49 -0
  144. package/tests/interest-collection/transactions-mutated.ts +260 -0
  145. package/tests/interest-oracle.test.ts +43 -35
  146. package/tests/mock/assets-mock.ts +234 -23
  147. package/tests/mock/protocol-params-mock.ts +21 -0
  148. package/tests/price-oracle/actions.ts +163 -0
  149. package/tests/price-oracle/price-oracle-queries.ts +12 -0
  150. package/tests/price-oracle/price-oracle.test.ts +240 -0
  151. package/tests/price-oracle/transactions-mutated.ts +62 -0
  152. package/tests/pyth/endpoints.ts +96 -0
  153. package/tests/pyth/helpers.ts +37 -0
  154. package/tests/pyth/pyth-encoding.test.ts +376 -0
  155. package/tests/pyth/pyth-indigo.test.ts +509 -0
  156. package/tests/pyth/pyth.test.ts +300 -0
  157. package/tests/queries/execute-queries.ts +6 -5
  158. package/tests/queries/iasset-queries.ts +175 -5
  159. package/tests/queries/interest-oracle-queries.ts +4 -2
  160. package/tests/queries/poll-queries.ts +8 -9
  161. package/tests/queries/stability-pool-queries.ts +95 -48
  162. package/tests/queries/staking-queries.ts +4 -2
  163. package/tests/queries/treasury-queries.ts +80 -5
  164. package/tests/rob/actions.ts +58 -0
  165. package/tests/{lrp-leverage.test.ts → rob/rob-leverage.test.ts} +393 -296
  166. package/tests/rob/rob-queries.ts +95 -0
  167. package/tests/rob/rob.test.ts +3762 -0
  168. package/tests/rob/transactions-mutated.ts +853 -0
  169. package/tests/script-size.test.ts +240 -0
  170. package/tests/setup.ts +135 -0
  171. package/tests/stability-pool/actions.ts +210 -0
  172. package/tests/stability-pool.test.ts +5469 -666
  173. package/tests/stableswap/stableswap-actions.ts +84 -0
  174. package/tests/stableswap/stableswap-queries.ts +89 -0
  175. package/tests/stableswap/stableswap.test.ts +3891 -0
  176. package/tests/stableswap/transactions-mutated.ts +348 -0
  177. package/tests/staking.test.ts +82 -99
  178. package/tests/test-helpers.ts +58 -11
  179. package/tests/treasury.test.ts +242 -0
  180. package/tests/utils/asserts.ts +74 -0
  181. package/tests/utils/benchmark-utils.ts +81 -0
  182. package/tests/utils/index.ts +122 -4
  183. package/tsconfig.json +9 -1
  184. package/vitest.config.ts +3 -1
  185. package/src/contracts/collector/types.ts +0 -16
  186. package/src/contracts/initialize/transactions.ts +0 -891
  187. package/src/contracts/leverage/helpers.ts +0 -424
  188. package/src/contracts/lrp/helpers.ts +0 -294
  189. package/src/contracts/lrp/scripts.ts +0 -27
  190. package/src/contracts/lrp/transactions.ts +0 -250
  191. package/src/contracts/lrp/types.ts +0 -131
  192. package/src/contracts/poll/types-poll.ts +0 -88
  193. package/src/contracts/vesting/helpers.ts +0 -218
  194. package/src/utils/value-helpers.ts +0 -37
  195. package/src/validators/lrp-validator.ts +0 -7
  196. package/tests/cdp.test.ts +0 -1528
  197. package/tests/gov.test.ts +0 -2011
  198. package/tests/lrp.test.ts +0 -673
  199. package/tests/queries/cdp-queries.ts +0 -220
  200. package/tests/queries/lrp-queries.ts +0 -76
  201. package/tests/queries/price-oracle-queries.ts +0 -10
@@ -0,0 +1,49 @@
1
+ import { LucidEvolution, UTxO } from '@lucid-evolution/lucid';
2
+ import { createScriptAddress, getRandomElement } from '../../src';
3
+ import { option as O, function as F } from 'fp-ts';
4
+ import {
5
+ AssetClass,
6
+ assetClassToUnit,
7
+ assetClassValueOf,
8
+ matchSingle,
9
+ } from '@3rd-eye-labs/cardano-offchain-common';
10
+
11
+ export async function findAllInterestCollectors(
12
+ lucid: LucidEvolution,
13
+ interestCollectorScriptHash: string,
14
+ ): Promise<UTxO[]> {
15
+ return lucid.utxosAt(
16
+ createScriptAddress(lucid.config().network!, interestCollectorScriptHash),
17
+ );
18
+ }
19
+
20
+ export async function findAdminInterestCollectors(
21
+ lucid: LucidEvolution,
22
+ interestCollectorScriptHash: string,
23
+ multisigUtxoNft: AssetClass,
24
+ ): Promise<UTxO> {
25
+ return matchSingle(
26
+ await lucid.utxosAtWithUnit(
27
+ createScriptAddress(lucid.config().network!, interestCollectorScriptHash),
28
+ assetClassToUnit(multisigUtxoNft),
29
+ ),
30
+ (_) => new Error('Expected a single admin interest collector UTXO'),
31
+ );
32
+ }
33
+
34
+ export async function findRandomNonAdminInterestCollector(
35
+ lucid: LucidEvolution,
36
+ interestCollectorScriptHash: string,
37
+ multisigUtxoNft: AssetClass,
38
+ ): Promise<UTxO> {
39
+ const allCollectors = (
40
+ await findAllInterestCollectors(lucid, interestCollectorScriptHash)
41
+ ).filter((utxo) => !assetClassValueOf(utxo.assets, multisigUtxoNft));
42
+
43
+ return F.pipe(
44
+ O.fromNullable(getRandomElement(allCollectors)),
45
+ O.match(() => {
46
+ throw new Error('Expected some non-admin interest collector UTXOs.');
47
+ }, F.identity),
48
+ );
49
+ }
@@ -0,0 +1,260 @@
1
+ import {
2
+ addAssets,
3
+ Address,
4
+ Assets,
5
+ Data,
6
+ LucidEvolution,
7
+ OutputDatum,
8
+ OutRef,
9
+ toHex,
10
+ TxBuilder,
11
+ UTxO,
12
+ } from '@lucid-evolution/lucid';
13
+ import {
14
+ fromSystemParamsScriptRef,
15
+ SystemParams,
16
+ matchSingle,
17
+ parseInterestCollectionDatum,
18
+ serialiseInterestCollectionDatum,
19
+ serialiseInterestCollectionRedeemer,
20
+ createScriptAddress,
21
+ fromSystemParamsAsset,
22
+ } from '../../src';
23
+ import {
24
+ assetClassValueOf,
25
+ getInlineDatumOrThrow,
26
+ } from '@3rd-eye-labs/cardano-offchain-common';
27
+ import { Multisig } from '../../src/types/multisig';
28
+
29
+ type CollectSuccess = {
30
+ kind: 'CollectSuccess';
31
+ };
32
+
33
+ type CollectWithoutCDP = {
34
+ kind: 'CollectWithoutCDP';
35
+ };
36
+
37
+ type CollectFromMultipleInterestCollectors = {
38
+ kind: 'CollectFromMultipleInterestCollectors';
39
+ utxo: UTxO;
40
+ };
41
+ type CollectFromInterestAdmin = {
42
+ kind: 'CollectFromInterestAdmin';
43
+ };
44
+ type CollectCustomValue = {
45
+ kind: 'CollectCustomValue';
46
+ value: Assets;
47
+ };
48
+
49
+ export type CollectInterestVariation =
50
+ | CollectSuccess
51
+ | CollectWithoutCDP
52
+ | CollectFromInterestAdmin
53
+ | CollectFromMultipleInterestCollectors
54
+ | CollectCustomValue;
55
+
56
+ export async function testCollectInterest(
57
+ value: Assets,
58
+ lucid: LucidEvolution,
59
+ params: SystemParams,
60
+ tx: TxBuilder,
61
+ interestCollectorOutRef: OutRef,
62
+ variation: CollectInterestVariation,
63
+ ): Promise<TxBuilder> {
64
+ const interestCollectorUtxo: UTxO = matchSingle(
65
+ await lucid.utxosByOutRef([interestCollectorOutRef]),
66
+ (_) => new Error('Expected a single interest collector UTXO'),
67
+ );
68
+
69
+ // Confirm that the interest collector UTXO is NOT of InterestCollectorDatum type
70
+ if (
71
+ variation.kind !== 'CollectFromInterestAdmin' &&
72
+ assetClassValueOf(
73
+ interestCollectorUtxo.assets,
74
+ fromSystemParamsAsset(params.interestCollectionParams.multisigUtxoNft),
75
+ )
76
+ ) {
77
+ throw new Error(
78
+ 'Interest collector UTXO is of InterestCollectorDatum type',
79
+ );
80
+ }
81
+
82
+ // Find the script reference UTXO for the interest collection validator
83
+ const interestCollectionRefScriptUtxo = matchSingle(
84
+ await lucid.utxosByOutRef([
85
+ fromSystemParamsScriptRef(
86
+ params.scriptReferences.interestCollectionValidatorRef,
87
+ ),
88
+ ]),
89
+ (_) => new Error('Expected a single interest collection Ref Script UTXO'),
90
+ );
91
+
92
+ // Collect the interest from the interest collector UTXO and then pay back with more assets.
93
+ tx.readFrom([interestCollectionRefScriptUtxo])
94
+ .collectFrom(
95
+ [interestCollectorUtxo],
96
+ serialiseInterestCollectionRedeemer('CollectInterest'),
97
+ )
98
+ .pay.ToContract(
99
+ createScriptAddress(
100
+ lucid.config().network!,
101
+ params.validatorHashes.interestCollectionHash,
102
+ ),
103
+ { kind: 'inline', value: Data.void() },
104
+ variation.kind === 'CollectCustomValue'
105
+ ? variation.value
106
+ : addAssets(interestCollectorUtxo.assets, value),
107
+ );
108
+
109
+ if (variation.kind === 'CollectFromMultipleInterestCollectors') {
110
+ tx.collectFrom(
111
+ [variation.utxo],
112
+ serialiseInterestCollectionRedeemer('CollectInterest'),
113
+ );
114
+ }
115
+
116
+ return tx;
117
+ }
118
+
119
+ type DistributeInterestNoAdmin = {
120
+ kind: 'DistributeInterestNoAdmin';
121
+ };
122
+ type DistributeInterestWithDatum = {
123
+ kind: 'DistributeInterestWithDatum';
124
+ datum: OutputDatum;
125
+ };
126
+ export type DistributeInterestVariation =
127
+ | DistributeInterestNoAdmin
128
+ | DistributeInterestWithDatum;
129
+
130
+ export async function testDistributeInterest(
131
+ interestCollectorOutRef: OutRef,
132
+ interestAdminOutRef: OutRef,
133
+ outputAddress: Address,
134
+ outputDatum: OutputDatum | undefined,
135
+ params: SystemParams,
136
+ lucid: LucidEvolution,
137
+ variation: DistributeInterestVariation,
138
+ ): Promise<TxBuilder> {
139
+ const interestCollectorUtxo: UTxO = matchSingle(
140
+ await lucid.utxosByOutRef([interestCollectorOutRef]),
141
+ (_) => new Error('Expected a single interest collector UTXO'),
142
+ );
143
+
144
+ const interestAdminUtxo: UTxO = matchSingle(
145
+ (await lucid.utxosByOutRef([interestAdminOutRef])).filter((utxo) =>
146
+ assetClassValueOf(
147
+ utxo.assets,
148
+ fromSystemParamsAsset(params.interestCollectionParams.multisigUtxoNft),
149
+ ),
150
+ ),
151
+ (_) => new Error('Expected a single interest admin UTXO'),
152
+ );
153
+
154
+ const interestAdminDatum = parseInterestCollectionDatum(
155
+ getInlineDatumOrThrow(interestAdminUtxo),
156
+ );
157
+
158
+ // Find the script reference UTXO for the interest collection validator
159
+ const interestCollectionRefScriptUtxo = matchSingle(
160
+ await lucid.utxosByOutRef([
161
+ fromSystemParamsScriptRef(
162
+ params.scriptReferences.interestCollectionValidatorRef,
163
+ ),
164
+ ]),
165
+ (_) => new Error('Expected a single interest collection Ref Script UTXO'),
166
+ );
167
+
168
+ const tx = lucid
169
+ .newTx()
170
+ .readFrom([interestCollectionRefScriptUtxo, interestAdminUtxo])
171
+ .collectFrom(
172
+ [interestCollectorUtxo],
173
+ serialiseInterestCollectionRedeemer('Distribute'),
174
+ )
175
+ .pay.ToContract(outputAddress, outputDatum, interestCollectorUtxo.assets);
176
+
177
+ if (variation.kind !== 'DistributeInterestNoAdmin') {
178
+ // TODO: Handle tx contruction for Multisig
179
+ if ('Signature' in interestAdminDatum.admin_permissions) {
180
+ tx.addSignerKey(
181
+ toHex(interestAdminDatum.admin_permissions.Signature.keyHash),
182
+ );
183
+ } else {
184
+ // TODO: Handle other admin permissions types
185
+ throw new Error('Unsupported admin permissions type');
186
+ }
187
+ }
188
+
189
+ return tx;
190
+ }
191
+
192
+ export async function updatePermissions(
193
+ interestAdminOutRef: OutRef,
194
+ newAdminPermissions: Multisig,
195
+ params: SystemParams,
196
+ lucid: LucidEvolution,
197
+ ): Promise<TxBuilder> {
198
+ const interestAdminUtxo: UTxO = matchSingle(
199
+ (await lucid.utxosByOutRef([interestAdminOutRef])).filter((utxo) =>
200
+ assetClassValueOf(
201
+ utxo.assets,
202
+ fromSystemParamsAsset(params.interestCollectionParams.multisigUtxoNft),
203
+ ),
204
+ ),
205
+ (_) => new Error('Expected a single interest admin UTXO'),
206
+ );
207
+
208
+ const interestAdminDatum = parseInterestCollectionDatum(
209
+ getInlineDatumOrThrow(interestAdminUtxo),
210
+ );
211
+
212
+ // Find the script reference UTXO for the interest collection validator
213
+ const interestCollectionRefScriptUtxo = matchSingle(
214
+ await lucid.utxosByOutRef([
215
+ fromSystemParamsScriptRef(
216
+ params.scriptReferences.interestCollectionValidatorRef,
217
+ ),
218
+ ]),
219
+ (_) => new Error('Expected a single interest collection Ref Script UTXO'),
220
+ );
221
+
222
+ const tx = lucid
223
+ .newTx()
224
+ .readFrom([interestCollectionRefScriptUtxo])
225
+ .collectFrom(
226
+ [interestAdminUtxo],
227
+ serialiseInterestCollectionRedeemer('UpdatePermissions'),
228
+ )
229
+ .pay.ToContract(
230
+ createScriptAddress(
231
+ lucid.config().network!,
232
+ params.validatorHashes.interestCollectionHash,
233
+ ),
234
+ {
235
+ kind: 'inline',
236
+ value: serialiseInterestCollectionDatum({
237
+ admin_permissions: newAdminPermissions,
238
+ }),
239
+ },
240
+ interestAdminUtxo.assets,
241
+ );
242
+
243
+ if ('Signature' in interestAdminDatum.admin_permissions) {
244
+ tx.addSignerKey(
245
+ toHex(interestAdminDatum.admin_permissions.Signature.keyHash),
246
+ );
247
+ } else {
248
+ // TODO: Handle other admin permissions types
249
+ throw new Error('Unsupported admin permissions type');
250
+ }
251
+
252
+ if ('Signature' in newAdminPermissions) {
253
+ tx.addSignerKey(toHex(newAdminPermissions.Signature.keyHash));
254
+ } else {
255
+ // TODO: Handle other admin permissions types
256
+ throw new Error('Unsupported admin permissions type');
257
+ }
258
+
259
+ return tx;
260
+ }
@@ -1,9 +1,5 @@
1
- import { afterEach, beforeEach, test } from 'vitest';
2
- import {
3
- LucidContext,
4
- runAndAwaitTx,
5
- runAndAwaitTxBuilder,
6
- } from './test-helpers';
1
+ import { beforeEach, test } from 'vitest';
2
+ import { LucidContext, runAndAwaitTxBuilder } from './test-helpers';
7
3
  import { EmulatorAccount, Lucid } from '@lucid-evolution/lucid';
8
4
  import { Emulator } from '@lucid-evolution/lucid';
9
5
  import { generateEmulatorAccount } from '@lucid-evolution/lucid';
@@ -14,36 +10,37 @@ import {
14
10
  startInterestOracle,
15
11
  } from '../src';
16
12
  import { findInterestOracle } from './queries/interest-oracle-queries';
13
+ import { benchmarkAndAwaitTx } from './utils/benchmark-utils';
14
+ import { MAINNET_PROTOCOL_PARAMETERS } from './indigo-test-helpers';
17
15
 
18
- type MyContext = LucidContext<{
16
+ type InterestOracleTestContext = LucidContext<{
17
+ admin: EmulatorAccount;
19
18
  user: EmulatorAccount;
20
19
  }>;
21
20
 
22
- let originalDateNow: () => number;
23
-
24
- beforeEach<MyContext>(async (context: MyContext) => {
25
- context.users = {
26
- user: generateEmulatorAccount({
27
- lovelace: BigInt(100_000_000_000_000),
28
- }),
29
- };
30
-
31
- context.emulator = new Emulator([context.users.user]);
32
-
33
- context.lucid = await Lucid(context.emulator, 'Custom');
34
-
35
- originalDateNow = Date.now;
36
- Date.now = () => context.emulator.now();
37
- });
38
-
39
- afterEach(() => {
40
- Date.now = originalDateNow;
41
- });
42
-
43
- test<MyContext>('Interest Oracle - Start', async ({
21
+ beforeEach<InterestOracleTestContext>(
22
+ async (context: InterestOracleTestContext) => {
23
+ context.users = {
24
+ admin: generateEmulatorAccount({}),
25
+ user: generateEmulatorAccount({
26
+ lovelace: BigInt(100_000_000_000_000),
27
+ }),
28
+ };
29
+
30
+ context.emulator = new Emulator(
31
+ [context.users.user],
32
+ MAINNET_PROTOCOL_PARAMETERS,
33
+ );
34
+
35
+ context.lucid = await Lucid(context.emulator, 'Custom');
36
+ },
37
+ );
38
+
39
+ test<InterestOracleTestContext>('Interest Oracle - Start', async ({
44
40
  lucid,
45
41
  users,
46
- }: MyContext) => {
42
+ emulator,
43
+ }: InterestOracleTestContext) => {
47
44
  lucid.selectWallet.fromSeed(users.user.seedPhrase);
48
45
 
49
46
  const [pkh, _] = await addrDetails(lucid);
@@ -59,13 +56,14 @@ test<MyContext>('Interest Oracle - Start', async ({
59
56
  lucid,
60
57
  );
61
58
 
62
- await runAndAwaitTxBuilder(lucid, tx);
59
+ await benchmarkAndAwaitTx('Interest Oracle - Start', tx, lucid, emulator);
63
60
  });
64
61
 
65
- test<MyContext>('Interest Oracle - Update', async ({
62
+ test<InterestOracleTestContext>('Interest Oracle - Update', async ({
66
63
  lucid,
67
64
  users,
68
- }: MyContext) => {
65
+ emulator,
66
+ }: InterestOracleTestContext) => {
69
67
  lucid.selectWallet.fromSeed(users.user.seedPhrase);
70
68
 
71
69
  const [pkh, _] = await addrDetails(lucid);
@@ -85,8 +83,18 @@ test<MyContext>('Interest Oracle - Update', async ({
85
83
  await runAndAwaitTxBuilder(lucid, tx);
86
84
 
87
85
  const utxo = await findInterestOracle(lucid, assetClass);
88
- await runAndAwaitTx(
86
+
87
+ await benchmarkAndAwaitTx(
88
+ 'Interest Oracle - Update',
89
+ await feedInterestOracle(
90
+ interestParams,
91
+ 500_000n,
92
+ lucid,
93
+ emulator.slot,
94
+ undefined,
95
+ utxo,
96
+ ),
89
97
  lucid,
90
- feedInterestOracle(interestParams, 500_000n, lucid, undefined, utxo),
98
+ emulator,
91
99
  );
92
100
  });
@@ -1,32 +1,243 @@
1
- export type { InitialAsset } from '../../src/contracts/initialize/types';
2
- import type { InitialAsset } from '../../src/contracts/initialize/types';
1
+ import {
2
+ AssetClass,
3
+ adaAssetClass,
4
+ } from '@3rd-eye-labs/cardano-offchain-common';
5
+ import { array as A, function as F, ord as Ord, string as Str } from 'fp-ts';
6
+ import {
7
+ DerivedPythPriceSP,
8
+ getAssetClassComparisonStr,
9
+ InitialAssetParam,
10
+ InitialCollateralAssetParam,
11
+ InitialStablepoolParam,
12
+ PythFeedParamsSP,
13
+ } from '../../src';
14
+ import { toHex } from '@lucid-evolution/lucid';
15
+ import { Rational, rationalFromInt } from '../../src/types/rational';
3
16
 
4
- export const iusdInitialAssetCfg: InitialAsset = {
5
- name: 'iUSD',
6
- priceOracle: {
7
- tokenName: 'iUSD_ORACLE',
8
- startPrice: 1_000_000n,
17
+ export const DEFAULT_INTEREST = 1_000_000n;
18
+ export const DEFAULT_PRICE = rationalFromInt(1n);
19
+
20
+ type IndigoOracleNftConfig = {
21
+ tag: '_indigo_oracle_nft';
22
+ tokenName: string;
23
+ startPrice: Rational;
24
+ params: {
25
+ biasTime: bigint;
26
+ expirationPeriod: bigint;
27
+ };
28
+ };
29
+
30
+ type PythOracleConfig = {
31
+ tag: '_pyth_oracle_nft';
32
+ pythFeedParams: PythFeedParamsSP;
33
+ };
34
+
35
+ export type InitialCollateralAsset = {
36
+ collateralAsset: AssetClass;
37
+ extraDecimals: bigint;
38
+ priceOracle: IndigoOracleNftConfig | PythOracleConfig;
39
+ interestOracle: {
40
+ tokenName: string;
41
+ initialInterestRate: bigint;
9
42
  params: {
10
- biasTime: 120_000n,
11
- expirationTime: 1_800_000n,
12
- },
13
- },
43
+ biasTime: bigint;
44
+ };
45
+ };
46
+ redemptionRatio: Rational;
47
+ maintenanceRatio: Rational;
48
+ liquidationRatio: Rational;
49
+ minCollateralAmt: bigint;
50
+ firstCollateralAsset: boolean;
51
+ nextCollateralAsset: AssetClass | undefined;
52
+ };
53
+
54
+ export type InitialAsset = {
55
+ name: string;
56
+ collateralAssets: InitialCollateralAsset[];
57
+ debtMintingFeeRatio: Rational;
58
+ liquidationProcessingFeeRatio: Rational;
59
+ stabilityPoolWithdrawalFeeRatio: Rational;
60
+ redemptionReimbursementRatio: Rational;
61
+ redemptionProcessingFeeRatio: Rational;
62
+ firstAsset: boolean;
63
+ nextAsset: string | undefined;
64
+ };
65
+
66
+ export function mkAssetsChain(
67
+ assets: InitialAssetParam[],
68
+ ): InitialAssetParam[] {
69
+ const sortedAssets = F.pipe(
70
+ assets,
71
+ A.sort(Ord.contramap<string, InitialAssetParam>((a) => a.name)(Str.Ord)),
72
+ );
73
+
74
+ return sortedAssets.map((asset, idx) => {
75
+ const isFirst = idx === 0;
76
+ const hasNext = idx < sortedAssets.length - 1;
77
+
78
+ return {
79
+ ...asset,
80
+ firstAsset: isFirst,
81
+ nextAsset: hasNext ? sortedAssets[idx + 1].name : undefined,
82
+ } satisfies InitialAssetParam;
83
+ });
84
+ }
85
+
86
+ export function mkCollateralAssetsChain(
87
+ assets: InitialCollateralAssetParam[],
88
+ ): InitialCollateralAssetParam[] {
89
+ const sortedAssets = F.pipe(
90
+ assets,
91
+ A.sort(
92
+ Ord.contramap<string, InitialCollateralAssetParam>((a) =>
93
+ getAssetClassComparisonStr(a.collateralAsset),
94
+ )(Str.Ord),
95
+ ),
96
+ );
97
+
98
+ return sortedAssets.map((asset, idx) => {
99
+ const isFirst = idx === 0;
100
+ const hasNext = idx < sortedAssets.length - 1;
101
+
102
+ return {
103
+ ...asset,
104
+ firstCollateralAsset: isFirst,
105
+ nextCollateralAsset: hasNext
106
+ ? sortedAssets[idx + 1].collateralAsset
107
+ : undefined,
108
+ } satisfies InitialCollateralAssetParam;
109
+ });
110
+ }
111
+
112
+ export const mkBaseCollateralAsset = (
113
+ a: AssetClass,
114
+ interest: bigint = DEFAULT_INTEREST,
115
+ initialPrice: Rational = DEFAULT_PRICE,
116
+ extraDecimals: bigint = 0n,
117
+ pythStateNft?: AssetClass,
118
+ pythDerivedPrice?: DerivedPythPriceSP,
119
+ ): InitialCollateralAssetParam => ({
120
+ collateralAsset: a,
121
+ extraDecimals: extraDecimals,
122
+ priceOracle:
123
+ pythStateNft && pythDerivedPrice
124
+ ? {
125
+ tag: '_pyth_oracle_nft',
126
+ pythFeedParams: {
127
+ config: pythDerivedPrice,
128
+ pythStatePolicyId: {
129
+ unCurrencySymbol: toHex(pythStateNft.currencySymbol),
130
+ },
131
+ },
132
+ }
133
+ : {
134
+ tag: '_indigo_oracle_nft',
135
+ tokenName: 'IASSET_ADA_ORACLE',
136
+ startPrice: initialPrice,
137
+ params: {
138
+ biasTime: 120_000n,
139
+ expirationPeriod: 1_800_000n,
140
+ },
141
+ },
14
142
  interestOracle: {
15
- tokenName: 'iUSD_ORACLE',
16
- initialInterestRate: 1_000_000n,
143
+ tokenName: 'IASSET_ADA_INTEREST_ORACLE',
144
+ initialInterestRate: interest,
17
145
  params: {
18
146
  biasTime: 120_000n,
19
147
  },
20
148
  },
21
- redemptionRatioPercentage: 200_000_000n,
22
- maintenanceRatioPercentage: 150_000_000n,
23
- liquidationRatioPercentage: 120_000_000n,
24
- debtMintingFeePercentage: 500_000n,
25
- liquidationProcessingFeePercentage: 2_000_000n,
26
- stabilityPoolWithdrawalFeePercentage: 500_000n,
27
- redemptionReimbursementPercentage: 1_000_000n,
28
- redemptionProcessingFeePercentage: 1_000_000n,
29
- interestCollectorPortionPercentage: 40_000_000n,
149
+ redemptionRatio: rationalFromInt(2n),
150
+ maintenanceRatio: { numerator: 15n, denominator: 10n },
151
+ liquidationRatio: { numerator: 12n, denominator: 10n },
152
+ minCollateralAmt: 10_000_000n,
153
+ firstCollateralAsset: true,
154
+ nextCollateralAsset: undefined,
155
+ });
156
+
157
+ export const iusdInitialAssetCfg = (
158
+ interest: bigint = DEFAULT_INTEREST,
159
+ stablepools: InitialStablepoolParam[] = [],
160
+ ): InitialAssetParam => ({
161
+ name: 'iUSD',
162
+ collateralAssets: [mkBaseCollateralAsset(adaAssetClass, interest)],
163
+ debtMintingFeeRatio: { numerator: 5n, denominator: 1_000n },
164
+ liquidationProcessingFeeRatio: { numerator: 2n, denominator: 100n },
165
+ stabilityPoolWithdrawalFeeRatio: { numerator: 5n, denominator: 1_000n },
166
+ redemptionReimbursementRatio: { numerator: 1n, denominator: 100n },
167
+ redemptionProcessingFeeRatio: { numerator: 1n, denominator: 100n },
30
168
  firstAsset: true,
31
169
  nextAsset: undefined,
32
- };
170
+ stablepools,
171
+ });
172
+
173
+ // Creates iUSD with a Pyth price oracle
174
+ export const iusdInitialAssetCfgWithPyth = (
175
+ pythStatePolicyId: AssetClass,
176
+ mkCollaterals: (
177
+ pythStatePolicyId: AssetClass,
178
+ ) => InitialCollateralAssetParam[],
179
+ ): InitialAssetParam => ({
180
+ name: 'iUSD',
181
+ collateralAssets: mkCollaterals(pythStatePolicyId),
182
+ stablepools: [],
183
+ debtMintingFeeRatio: { numerator: 5n, denominator: 1_000n },
184
+ liquidationProcessingFeeRatio: { numerator: 2n, denominator: 100n },
185
+ stabilityPoolWithdrawalFeeRatio: { numerator: 5n, denominator: 1_000n },
186
+ redemptionReimbursementRatio: { numerator: 1n, denominator: 100n },
187
+ redemptionProcessingFeeRatio: { numerator: 1n, denominator: 100n },
188
+ firstAsset: true,
189
+ nextAsset: undefined,
190
+ });
191
+
192
+ // Creates iETH with a Pyth price oracle
193
+ export const iethInitialAssetCfgWithPyth = (
194
+ pythStatePolicyId: AssetClass,
195
+ mkCollaterals: (
196
+ pythStatePolicyId: AssetClass,
197
+ ) => InitialCollateralAssetParam[],
198
+ ): InitialAssetParam => ({
199
+ name: 'iETH',
200
+ collateralAssets: mkCollaterals(pythStatePolicyId),
201
+ stablepools: [],
202
+ debtMintingFeeRatio: { numerator: 5n, denominator: 1_000n },
203
+ liquidationProcessingFeeRatio: { numerator: 2n, denominator: 100n },
204
+ stabilityPoolWithdrawalFeeRatio: { numerator: 5n, denominator: 1_000n },
205
+ redemptionReimbursementRatio: { numerator: 1n, denominator: 100n },
206
+ redemptionProcessingFeeRatio: { numerator: 1n, denominator: 100n },
207
+ firstAsset: true,
208
+ nextAsset: undefined,
209
+ });
210
+
211
+ // Creates iBTC with a Pyth price oracle
212
+ export const ibtcInitialAssetCfgWithPyth = (
213
+ pythStatePolicyId: AssetClass,
214
+ mkCollaterals: (
215
+ pythStatePolicyId: AssetClass,
216
+ ) => InitialCollateralAssetParam[],
217
+ ): InitialAssetParam => ({
218
+ name: 'iBTC',
219
+ collateralAssets: mkCollaterals(pythStatePolicyId),
220
+ stablepools: [],
221
+ debtMintingFeeRatio: { numerator: 5n, denominator: 1_000n },
222
+ liquidationProcessingFeeRatio: { numerator: 2n, denominator: 100n },
223
+ stabilityPoolWithdrawalFeeRatio: { numerator: 5n, denominator: 1_000n },
224
+ redemptionReimbursementRatio: { numerator: 1n, denominator: 100n },
225
+ redemptionProcessingFeeRatio: { numerator: 1n, denominator: 100n },
226
+ firstAsset: true,
227
+ nextAsset: undefined,
228
+ });
229
+
230
+ export const ieurInitialAssetCfg = (
231
+ interest: bigint = DEFAULT_INTEREST,
232
+ ): InitialAssetParam => ({
233
+ name: 'iEUR',
234
+ collateralAssets: [mkBaseCollateralAsset(adaAssetClass, interest)],
235
+ stablepools: [],
236
+ debtMintingFeeRatio: { numerator: 5n, denominator: 1_000n },
237
+ liquidationProcessingFeeRatio: { numerator: 2n, denominator: 100n },
238
+ stabilityPoolWithdrawalFeeRatio: { numerator: 5n, denominator: 1_000n },
239
+ redemptionReimbursementRatio: { numerator: 1n, denominator: 100n },
240
+ redemptionProcessingFeeRatio: { numerator: 1n, denominator: 100n },
241
+ firstAsset: true,
242
+ nextAsset: undefined,
243
+ });