@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.
- package/.github/workflows/ci.yml +4 -2
- package/dist/index.d.mts +3008 -2194
- package/dist/index.d.ts +3008 -2194
- package/dist/index.js +9827 -6194
- package/dist/index.mjs +8591 -4809
- package/package.json +14 -3
- package/src/contracts/cdp/helpers.ts +68 -72
- package/src/contracts/cdp/scripts.ts +50 -13
- package/src/contracts/cdp/transactions.ts +831 -545
- package/src/contracts/cdp/types-new.ts +256 -0
- package/src/contracts/cdp/types.ts +26 -144
- package/src/contracts/cdp-creator/scripts.ts +15 -9
- package/src/contracts/cdp-creator/types-new.ts +50 -0
- package/src/contracts/cdp-creator/types.ts +5 -31
- package/src/contracts/collector/scripts.ts +1 -1
- package/src/contracts/collector/transactions.ts +23 -13
- package/src/contracts/collector/types-new.ts +17 -0
- package/src/contracts/execute/scripts.ts +19 -10
- package/src/contracts/execute/types-new.ts +44 -0
- package/src/contracts/execute/types.ts +5 -38
- package/src/contracts/gov/helpers.ts +187 -51
- package/src/contracts/gov/scripts.ts +17 -10
- package/src/contracts/gov/transactions.ts +599 -271
- package/src/contracts/gov/types-new.ts +253 -100
- package/src/contracts/gov/types.ts +4 -71
- package/src/contracts/iasset/helpers.ts +172 -0
- package/src/contracts/iasset/scripts.ts +38 -0
- package/src/contracts/iasset/types.ts +154 -0
- package/src/contracts/initialize/actions.ts +768 -0
- package/src/contracts/initialize/helpers.ts +611 -36
- package/src/contracts/initialize/types.ts +102 -28
- package/src/contracts/interest-collection/helpers.ts +19 -0
- package/src/contracts/interest-collection/scripts.ts +44 -0
- package/src/contracts/interest-collection/transactions.ts +436 -0
- package/src/contracts/interest-collection/types-new.ts +50 -0
- package/src/contracts/interest-collection/types.ts +26 -0
- package/src/contracts/interest-oracle/helpers.ts +2 -30
- package/src/contracts/interest-oracle/scripts.ts +1 -1
- package/src/contracts/interest-oracle/transactions.ts +21 -16
- package/src/contracts/interest-oracle/types-new.ts +32 -0
- package/src/contracts/interest-oracle/types.ts +1 -40
- package/src/contracts/one-shot/transactions.ts +1 -2
- package/src/contracts/poll/helpers.ts +5 -23
- package/src/contracts/poll/scripts.ts +12 -13
- package/src/contracts/poll/types-poll-manager.ts +1 -19
- package/src/contracts/poll/types-poll-new.ts +170 -0
- package/src/contracts/poll/types-poll-shard.ts +2 -24
- package/src/contracts/price-oracle/helpers.ts +1 -4
- package/src/contracts/price-oracle/scripts.ts +3 -8
- package/src/contracts/price-oracle/transactions.ts +32 -25
- package/src/contracts/price-oracle/types-new.ts +50 -0
- package/src/contracts/price-oracle/types.ts +2 -36
- package/src/contracts/pyth-feed/helpers.ts +58 -0
- package/src/contracts/pyth-feed/scripts.ts +15 -0
- package/src/contracts/pyth-feed/types.ts +181 -0
- package/src/contracts/rob/helpers.ts +405 -0
- package/src/contracts/rob/scripts.ts +35 -0
- package/src/contracts/rob/transactions.ts +410 -0
- package/src/contracts/rob/types-new.ts +128 -0
- package/src/contracts/rob/types.ts +16 -0
- package/src/contracts/rob-leverage/helpers.ts +424 -0
- package/src/contracts/{leverage → rob-leverage}/transactions.ts +68 -48
- package/src/contracts/stability-pool/helpers.ts +714 -230
- package/src/contracts/stability-pool/scripts.ts +20 -15
- package/src/contracts/stability-pool/transactions.ts +625 -495
- package/src/contracts/stability-pool/types-new.ts +237 -100
- package/src/contracts/stability-pool/types.ts +5 -22
- package/src/contracts/stableswap/helpers.ts +22 -0
- package/src/contracts/stableswap/scripts.ts +37 -0
- package/src/contracts/stableswap/transactions.ts +647 -0
- package/src/contracts/stableswap/types-new.ts +131 -0
- package/src/contracts/stableswap/types.ts +17 -0
- package/src/contracts/staking/helpers.ts +49 -34
- package/src/contracts/staking/scripts.ts +1 -1
- package/src/contracts/staking/transactions.ts +85 -130
- package/src/contracts/staking/types-new.ts +60 -28
- package/src/contracts/staking/types.ts +1 -28
- package/src/contracts/treasury/helpers.ts +21 -0
- package/src/contracts/treasury/scripts.ts +16 -26
- package/src/contracts/treasury/transactions.ts +256 -27
- package/src/contracts/treasury/types-new.ts +69 -0
- package/src/contracts/treasury/types.ts +2 -43
- package/src/contracts/version-registry/scripts.ts +2 -2
- package/src/contracts/version-registry/types-new.ts +6 -7
- package/src/index.ts +37 -20
- package/src/scripts/auth-token-policy.ts +3 -2
- package/src/scripts/iasset-policy.ts +3 -2
- package/src/types/evolution-schema-options.ts +3 -3
- package/src/types/generic.ts +17 -89
- package/src/types/multisig.ts +48 -0
- package/src/types/on-chain-decimal.ts +14 -7
- package/src/types/rational.ts +61 -0
- package/src/types/system-params.ts +237 -41
- package/src/utils/array-utils.ts +70 -1
- package/src/utils/bigint-utils.ts +12 -0
- package/src/utils/indigo-helpers.ts +8 -10
- package/src/utils/lucid-utils.ts +47 -40
- package/src/utils/oracle-helpers.ts +62 -0
- package/src/utils/pyth/decode.ts +223 -0
- package/src/utils/pyth/encode.ts +262 -0
- package/src/utils/pyth/index.ts +14 -0
- package/src/utils/pyth/types.ts +87 -0
- package/src/validators/always-succeed-validator.ts +6 -0
- package/src/validators/cdp-creator-validator.ts +2 -2
- package/src/validators/cdp-redeem-validator.ts +7 -0
- package/src/validators/cdp-validator.ts +2 -2
- package/src/validators/collector-validator.ts +2 -2
- package/src/validators/execute-validator.ts +2 -2
- package/src/validators/governance-validator.ts +2 -2
- package/src/validators/iasset-validator.ts +7 -0
- package/src/validators/interest-collection-validator.ts +7 -0
- package/src/validators/interest-oracle-validator.ts +2 -2
- package/src/validators/poll-manager-validator.ts +2 -2
- package/src/validators/poll-shard-validator.ts +2 -2
- package/src/validators/price-oracle-validator.ts +7 -0
- package/src/validators/pyth-feed-validator.ts +7 -0
- package/src/validators/rob-validator.ts +7 -0
- package/src/validators/stability-pool-validator.ts +2 -2
- package/src/validators/stableswap-validator.ts +7 -0
- package/src/validators/staking-validator.ts +2 -2
- package/src/validators/treasury-validator.ts +2 -2
- package/src/validators/version-record-policy.ts +2 -2
- package/src/validators/version-registry-validator.ts +2 -2
- package/tests/always-succeed/script.ts +7 -0
- package/tests/bigint-utils.test.ts +41 -0
- package/tests/cdp/actions.ts +611 -0
- package/tests/cdp/cdp-helpers.ts +55 -0
- package/tests/cdp/cdp-queries.ts +440 -0
- package/tests/cdp/cdp.test.ts +6087 -0
- package/tests/cdp/transactions-mutated.ts +1729 -0
- package/tests/data/system-params.json +177 -34
- package/tests/datums.test.ts +209 -210
- package/tests/endpoints/initialize.ts +68 -0
- package/tests/endpoints/interest-collector.ts +37 -0
- package/tests/endpoints/treasury.ts +70 -0
- package/tests/gov/actions.ts +406 -0
- package/tests/gov/gov.test.ts +4450 -0
- package/tests/{queries → gov}/governance-queries.ts +6 -3
- package/tests/hash-checks.test.ts +38 -11
- package/tests/indigo-test-helpers.ts +100 -0
- package/tests/initialize.test.ts +61 -9
- package/tests/interest-collection/interest-collection.test.ts +892 -0
- package/tests/interest-collection/interest-collector-queries.ts +49 -0
- package/tests/interest-collection/transactions-mutated.ts +260 -0
- package/tests/interest-oracle.test.ts +43 -35
- package/tests/mock/assets-mock.ts +234 -23
- package/tests/mock/protocol-params-mock.ts +21 -0
- package/tests/price-oracle/actions.ts +163 -0
- package/tests/price-oracle/price-oracle-queries.ts +12 -0
- package/tests/price-oracle/price-oracle.test.ts +240 -0
- package/tests/price-oracle/transactions-mutated.ts +62 -0
- package/tests/pyth/endpoints.ts +96 -0
- package/tests/pyth/helpers.ts +37 -0
- package/tests/pyth/pyth-encoding.test.ts +376 -0
- package/tests/pyth/pyth-indigo.test.ts +509 -0
- package/tests/pyth/pyth.test.ts +300 -0
- package/tests/queries/execute-queries.ts +6 -5
- package/tests/queries/iasset-queries.ts +175 -5
- package/tests/queries/interest-oracle-queries.ts +4 -2
- package/tests/queries/poll-queries.ts +8 -9
- package/tests/queries/stability-pool-queries.ts +95 -48
- package/tests/queries/staking-queries.ts +4 -2
- package/tests/queries/treasury-queries.ts +80 -5
- package/tests/rob/actions.ts +58 -0
- package/tests/{lrp-leverage.test.ts → rob/rob-leverage.test.ts} +393 -296
- package/tests/rob/rob-queries.ts +95 -0
- package/tests/rob/rob.test.ts +3762 -0
- package/tests/rob/transactions-mutated.ts +853 -0
- package/tests/script-size.test.ts +240 -0
- package/tests/setup.ts +135 -0
- package/tests/stability-pool/actions.ts +210 -0
- package/tests/stability-pool.test.ts +5469 -666
- package/tests/stableswap/stableswap-actions.ts +84 -0
- package/tests/stableswap/stableswap-queries.ts +89 -0
- package/tests/stableswap/stableswap.test.ts +3891 -0
- package/tests/stableswap/transactions-mutated.ts +348 -0
- package/tests/staking.test.ts +82 -99
- package/tests/test-helpers.ts +58 -11
- package/tests/treasury.test.ts +242 -0
- package/tests/utils/asserts.ts +74 -0
- package/tests/utils/benchmark-utils.ts +81 -0
- package/tests/utils/index.ts +122 -4
- package/tsconfig.json +9 -1
- package/vitest.config.ts +3 -1
- package/src/contracts/collector/types.ts +0 -16
- package/src/contracts/initialize/transactions.ts +0 -891
- package/src/contracts/leverage/helpers.ts +0 -424
- package/src/contracts/lrp/helpers.ts +0 -294
- package/src/contracts/lrp/scripts.ts +0 -27
- package/src/contracts/lrp/transactions.ts +0 -250
- package/src/contracts/lrp/types.ts +0 -131
- package/src/contracts/poll/types-poll.ts +0 -88
- package/src/contracts/vesting/helpers.ts +0 -218
- package/src/utils/value-helpers.ts +0 -37
- package/src/validators/lrp-validator.ts +0 -7
- package/tests/cdp.test.ts +0 -1528
- package/tests/gov.test.ts +0 -2011
- package/tests/lrp.test.ts +0 -673
- package/tests/queries/cdp-queries.ts +0 -220
- package/tests/queries/lrp-queries.ts +0 -76
- 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 {
|
|
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
|
|
16
|
+
type InterestOracleTestContext = LucidContext<{
|
|
17
|
+
admin: EmulatorAccount;
|
|
19
18
|
user: EmulatorAccount;
|
|
20
19
|
}>;
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
|
|
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
|
|
59
|
+
await benchmarkAndAwaitTx('Interest Oracle - Start', tx, lucid, emulator);
|
|
63
60
|
});
|
|
64
61
|
|
|
65
|
-
test<
|
|
62
|
+
test<InterestOracleTestContext>('Interest Oracle - Update', async ({
|
|
66
63
|
lucid,
|
|
67
64
|
users,
|
|
68
|
-
|
|
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
|
-
|
|
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
|
-
|
|
98
|
+
emulator,
|
|
91
99
|
);
|
|
92
100
|
});
|
|
@@ -1,32 +1,243 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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:
|
|
11
|
-
|
|
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: '
|
|
16
|
-
initialInterestRate:
|
|
143
|
+
tokenName: 'IASSET_ADA_INTEREST_ORACLE',
|
|
144
|
+
initialInterestRate: interest,
|
|
17
145
|
params: {
|
|
18
146
|
biasTime: 120_000n,
|
|
19
147
|
},
|
|
20
148
|
},
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
+
});
|