@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
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
addAssets,
|
|
3
3
|
Assets,
|
|
4
|
+
credentialToRewardAddress,
|
|
4
5
|
Data,
|
|
6
|
+
fromHex,
|
|
7
|
+
getInputIndices,
|
|
5
8
|
LucidEvolution,
|
|
6
9
|
OutRef,
|
|
10
|
+
scriptHashToCredential,
|
|
7
11
|
slotToUnixTime,
|
|
12
|
+
toHex,
|
|
8
13
|
TxBuilder,
|
|
9
14
|
UTxO,
|
|
10
15
|
} from '@lucid-evolution/lucid';
|
|
@@ -17,59 +22,73 @@ import {
|
|
|
17
22
|
addrDetails,
|
|
18
23
|
createScriptAddress,
|
|
19
24
|
getInlineDatumOrThrow,
|
|
20
|
-
resolveUtxo,
|
|
21
|
-
UtxoOrOutRef,
|
|
22
25
|
} from '../../utils/lucid-utils';
|
|
23
26
|
import { matchSingle } from '../../utils/utils';
|
|
24
|
-
import {
|
|
25
|
-
CDPContent,
|
|
26
|
-
parseCdpDatumOrThrow,
|
|
27
|
-
parseIAssetDatumOrThrow,
|
|
28
|
-
serialiseCdpDatum,
|
|
29
|
-
serialiseCdpRedeemer,
|
|
30
|
-
} from './types';
|
|
31
|
-
import { parsePriceOracleDatum } from '../price-oracle/types';
|
|
32
|
-
import { parseInterestOracleDatum } from '../interest-oracle/types';
|
|
33
|
-
import { parseGovDatumOrThrow } from '../gov/types';
|
|
34
27
|
import {
|
|
35
28
|
calculateAccruedInterest,
|
|
36
29
|
calculateUnitaryInterestSinceOracleLastUpdated,
|
|
37
|
-
computeInterestLovelacesFor100PercentCR,
|
|
38
30
|
} from '../interest-oracle/helpers';
|
|
39
31
|
import { oracleExpirationAwareValidity } from '../price-oracle/helpers';
|
|
40
32
|
import { match, P } from 'ts-pattern';
|
|
41
|
-
|
|
42
|
-
import {
|
|
43
|
-
assetClassValueOf,
|
|
44
|
-
lovelacesAmt,
|
|
45
|
-
mkAssetsOf,
|
|
46
|
-
mkLovelacesOf,
|
|
47
|
-
} from '../../utils/value-helpers';
|
|
33
|
+
|
|
48
34
|
import { calculateMinCollateralCappedIAssetRedemptionAmt } from './helpers';
|
|
49
|
-
import { bigintMin } from '../../utils/bigint-utils';
|
|
50
|
-
import { ocdMul } from '../../types/on-chain-decimal';
|
|
35
|
+
import { bigintMax, bigintMin } from '../../utils/bigint-utils';
|
|
51
36
|
import {
|
|
52
|
-
|
|
37
|
+
parseStabilityPoolDatumOrThrow,
|
|
53
38
|
serialiseStabilityPoolDatum,
|
|
54
39
|
serialiseStabilityPoolRedeemer,
|
|
55
40
|
} from '../stability-pool/types-new';
|
|
56
41
|
import { liquidationHelper } from '../stability-pool/helpers';
|
|
57
|
-
import { array as A, function as F } from 'fp-ts';
|
|
58
|
-
import {
|
|
59
|
-
import {
|
|
42
|
+
import { array as A, function as F, option as O } from 'fp-ts';
|
|
43
|
+
import { calculateFeeFromRatio } from '../../utils/indigo-helpers';
|
|
44
|
+
import { collectInterestTx } from '../interest-collection/transactions';
|
|
45
|
+
import {
|
|
46
|
+
CDPContent,
|
|
47
|
+
parseCdpDatumOrThrow,
|
|
48
|
+
serialiseCdpDatum,
|
|
49
|
+
serialiseCdpRedeemer,
|
|
50
|
+
serialiseRedeemCdpWithdrawalRedeemer,
|
|
51
|
+
} from './types-new';
|
|
52
|
+
import { parseGovDatumOrThrow } from '../gov/types-new';
|
|
53
|
+
import {
|
|
54
|
+
adaAssetClass,
|
|
55
|
+
assetClassValueOf,
|
|
56
|
+
mkAssetsOf,
|
|
57
|
+
negateAssets,
|
|
58
|
+
} from '@3rd-eye-labs/cardano-offchain-common';
|
|
59
|
+
import { parsePriceOracleDatum } from '../price-oracle/types-new';
|
|
60
|
+
import { parseInterestOracleDatum } from '../interest-oracle/types-new';
|
|
61
|
+
import {
|
|
62
|
+
serialiseCDPCreatorDatum,
|
|
63
|
+
serialiseCDPCreatorRedeemer,
|
|
64
|
+
} from '../cdp-creator/types-new';
|
|
65
|
+
import {
|
|
66
|
+
parseCollateralAssetDatumOrThrow,
|
|
67
|
+
parseIAssetDatumOrThrow,
|
|
68
|
+
} from '../iasset/types';
|
|
60
69
|
import { treasuryFeeTx } from '../treasury/transactions';
|
|
70
|
+
import { attachOracle } from '../iasset/helpers';
|
|
71
|
+
import {
|
|
72
|
+
rationalFloor,
|
|
73
|
+
rationalFromInt,
|
|
74
|
+
rationalMul,
|
|
75
|
+
} from '../../types/rational';
|
|
76
|
+
import { retrieveAdjustedPrice } from '../../utils/oracle-helpers';
|
|
61
77
|
|
|
62
78
|
export async function openCdp(
|
|
63
79
|
collateralAmount: bigint,
|
|
64
80
|
mintedAmount: bigint,
|
|
65
81
|
sysParams: SystemParams,
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
82
|
+
cdpCreatorOref: OutRef,
|
|
83
|
+
iassetOref: OutRef,
|
|
84
|
+
collateralAssetOref: OutRef,
|
|
85
|
+
priceOracleOref: OutRef | undefined,
|
|
86
|
+
interestOracleOref: OutRef,
|
|
87
|
+
treasuryOref: OutRef,
|
|
71
88
|
lucid: LucidEvolution,
|
|
72
89
|
currentSlot: number,
|
|
90
|
+
pythMessage: string | undefined = undefined,
|
|
91
|
+
pythStateOref: OutRef | undefined = undefined,
|
|
73
92
|
): Promise<TxBuilder> {
|
|
74
93
|
const network = lucid.config().network!;
|
|
75
94
|
const currentTime = BigInt(slotToUnixTime(network, currentSlot));
|
|
@@ -101,40 +120,36 @@ export async function openCdp(
|
|
|
101
120
|
(_) => new Error('Expected a single iasset token policy Ref Script UTXO'),
|
|
102
121
|
);
|
|
103
122
|
|
|
104
|
-
const iassetUtxo =
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
'Expected a single iasset UTXO',
|
|
123
|
+
const iassetUtxo = matchSingle(
|
|
124
|
+
await lucid.utxosByOutRef([iassetOref]),
|
|
125
|
+
(_) => new Error('Expected a single iasset UTXO'),
|
|
108
126
|
);
|
|
109
127
|
const iassetDatum = parseIAssetDatumOrThrow(
|
|
110
128
|
getInlineDatumOrThrow(iassetUtxo),
|
|
111
129
|
);
|
|
112
130
|
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
'Expected a single price oracle UTXO',
|
|
131
|
+
const collateralAssetUtxo = matchSingle(
|
|
132
|
+
await lucid.utxosByOutRef([collateralAssetOref]),
|
|
133
|
+
(_) => new Error('Expected a single collateral asset UTXO'),
|
|
117
134
|
);
|
|
118
|
-
const
|
|
119
|
-
getInlineDatumOrThrow(
|
|
135
|
+
const collateralAssetDatum = parseCollateralAssetDatumOrThrow(
|
|
136
|
+
getInlineDatumOrThrow(collateralAssetUtxo),
|
|
120
137
|
);
|
|
121
138
|
|
|
122
|
-
const interestOracleUtxo =
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
'Expected a single interest oracle UTXO',
|
|
139
|
+
const interestOracleUtxo = matchSingle(
|
|
140
|
+
await lucid.utxosByOutRef([interestOracleOref]),
|
|
141
|
+
(_) => new Error('Expected a single interest oracle UTXO'),
|
|
126
142
|
);
|
|
127
143
|
const interestOracleDatum = parseInterestOracleDatum(
|
|
128
144
|
getInlineDatumOrThrow(interestOracleUtxo),
|
|
129
145
|
);
|
|
130
146
|
|
|
131
|
-
const cdpCreatorUtxo =
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
'Expected a single CDP creator UTXO',
|
|
147
|
+
const cdpCreatorUtxo = matchSingle(
|
|
148
|
+
await lucid.utxosByOutRef([cdpCreatorOref]),
|
|
149
|
+
(_) => new Error('Expected a single CDP creator UTXO'),
|
|
135
150
|
);
|
|
136
151
|
|
|
137
|
-
match(
|
|
152
|
+
match(collateralAssetDatum.priceInfo)
|
|
138
153
|
.with({ Delisted: P.any }, () => {
|
|
139
154
|
throw new Error("Can't open CDP of delisted asset");
|
|
140
155
|
})
|
|
@@ -145,50 +160,41 @@ export async function openCdp(
|
|
|
145
160
|
1n,
|
|
146
161
|
);
|
|
147
162
|
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
);
|
|
163
|
+
const iassetClass = {
|
|
164
|
+
currencySymbol: fromHex(
|
|
165
|
+
sysParams.cdpParams.cdpAssetSymbol.unCurrencySymbol,
|
|
166
|
+
),
|
|
167
|
+
tokenName: iassetDatum.assetName,
|
|
168
|
+
};
|
|
155
169
|
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
170
|
+
const iassetTokensVal = mkAssetsOf(iassetClass, mintedAmount);
|
|
171
|
+
|
|
172
|
+
const refScripts: UTxO[] = [
|
|
173
|
+
cdpCreatorRefScriptUtxo,
|
|
174
|
+
cdpAuthTokenPolicyRefScriptUtxo,
|
|
175
|
+
iAssetTokenPolicyRefScriptUtxo,
|
|
176
|
+
];
|
|
177
|
+
|
|
178
|
+
const referenceInputs: UTxO[] = [
|
|
179
|
+
interestOracleUtxo,
|
|
180
|
+
iassetUtxo,
|
|
181
|
+
collateralAssetUtxo,
|
|
182
|
+
];
|
|
162
183
|
|
|
163
184
|
const tx = lucid
|
|
164
185
|
.newTx()
|
|
165
|
-
|
|
166
|
-
.
|
|
167
|
-
.readFrom([
|
|
168
|
-
cdpCreatorRefScriptUtxo,
|
|
169
|
-
cdpAuthTokenPolicyRefScriptUtxo,
|
|
170
|
-
iAssetTokenPolicyRefScriptUtxo,
|
|
171
|
-
])
|
|
186
|
+
// Ref scripts
|
|
187
|
+
.readFrom(refScripts)
|
|
172
188
|
.mintAssets(cdpNftVal, Data.void())
|
|
173
189
|
.mintAssets(iassetTokensVal, Data.void())
|
|
174
|
-
.collectFrom(
|
|
175
|
-
[cdpCreatorUtxo],
|
|
176
|
-
serialiseCDPCreatorRedeemer({
|
|
177
|
-
CreateCDP: {
|
|
178
|
-
cdpOwner: pkh.hash,
|
|
179
|
-
minted: mintedAmount,
|
|
180
|
-
collateral: collateralAmount,
|
|
181
|
-
currentTime: currentTime,
|
|
182
|
-
},
|
|
183
|
-
}),
|
|
184
|
-
)
|
|
185
190
|
.pay.ToContract(
|
|
186
191
|
createScriptAddress(network, sysParams.validatorHashes.cdpHash, skh),
|
|
187
192
|
{
|
|
188
193
|
kind: 'inline',
|
|
189
194
|
value: serialiseCdpDatum({
|
|
190
|
-
cdpOwner: pkh.hash,
|
|
195
|
+
cdpOwner: fromHex(pkh.hash),
|
|
191
196
|
iasset: iassetDatum.assetName,
|
|
197
|
+
collateralAsset: collateralAssetDatum.collateralAsset,
|
|
192
198
|
mintedAmt: mintedAmount,
|
|
193
199
|
cdpFees: {
|
|
194
200
|
ActiveCDPInterestTracking: {
|
|
@@ -202,41 +208,115 @@ export async function openCdp(
|
|
|
202
208
|
},
|
|
203
209
|
}),
|
|
204
210
|
},
|
|
205
|
-
addAssets(
|
|
211
|
+
addAssets(
|
|
212
|
+
cdpNftVal,
|
|
213
|
+
mkAssetsOf(collateralAssetDatum.collateralAsset, collateralAmount),
|
|
214
|
+
),
|
|
206
215
|
)
|
|
207
216
|
.pay.ToContract(
|
|
208
217
|
cdpCreatorUtxo.address,
|
|
209
|
-
{
|
|
218
|
+
{
|
|
219
|
+
kind: 'inline',
|
|
220
|
+
value: serialiseCDPCreatorDatum({
|
|
221
|
+
creatorInputOref: {
|
|
222
|
+
outputIndex: BigInt(cdpCreatorUtxo.outputIndex),
|
|
223
|
+
txHash: fromHex(cdpCreatorUtxo.txHash),
|
|
224
|
+
},
|
|
225
|
+
}),
|
|
226
|
+
},
|
|
210
227
|
cdpCreatorUtxo.assets,
|
|
211
|
-
)
|
|
212
|
-
.readFrom([priceOracleUtxo, interestOracleUtxo, iassetUtxo])
|
|
213
|
-
.addSignerKey(pkh.hash);
|
|
228
|
+
);
|
|
214
229
|
|
|
215
|
-
const
|
|
216
|
-
iassetDatum.
|
|
217
|
-
|
|
230
|
+
const { interval, referenceInputs: refInputs } = await attachOracle(
|
|
231
|
+
iassetDatum.assetName,
|
|
232
|
+
collateralAssetDatum.collateralAsset,
|
|
233
|
+
collateralAssetDatum.priceInfo,
|
|
234
|
+
priceOracleOref,
|
|
235
|
+
pythStateOref,
|
|
236
|
+
pythMessage,
|
|
237
|
+
sysParams.pythConfig,
|
|
238
|
+
sysParams.cdpCreatorParams.biasTime,
|
|
239
|
+
currentSlot,
|
|
240
|
+
lucid,
|
|
241
|
+
tx,
|
|
218
242
|
);
|
|
219
243
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
244
|
+
// Set the validity interval for the transaction
|
|
245
|
+
tx.validFrom(interval.validFrom).validTo(interval.validTo);
|
|
246
|
+
|
|
247
|
+
// Read from the reference inputs
|
|
248
|
+
referenceInputs.push(...refInputs);
|
|
249
|
+
|
|
250
|
+
tx.readFrom(referenceInputs);
|
|
251
|
+
|
|
252
|
+
const debtMintingFee = calculateFeeFromRatio(
|
|
253
|
+
iassetDatum.debtMintingFeeRatio,
|
|
254
|
+
mintedAmount,
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
const treasuryRefScriptUtxo =
|
|
258
|
+
debtMintingFee > 0
|
|
259
|
+
? await treasuryFeeTx(
|
|
260
|
+
iassetClass,
|
|
261
|
+
debtMintingFee,
|
|
262
|
+
0n,
|
|
263
|
+
lucid,
|
|
264
|
+
sysParams,
|
|
265
|
+
tx,
|
|
266
|
+
cdpCreatorUtxo,
|
|
267
|
+
treasuryOref,
|
|
268
|
+
)
|
|
269
|
+
: undefined;
|
|
270
|
+
|
|
271
|
+
// We need to take into account the treasury ref script as well.
|
|
272
|
+
const refInputsIndices = getInputIndices(referenceInputs, [
|
|
273
|
+
...referenceInputs,
|
|
274
|
+
...refScripts,
|
|
275
|
+
...(treasuryRefScriptUtxo != null ? [treasuryRefScriptUtxo] : []),
|
|
276
|
+
]);
|
|
277
|
+
|
|
278
|
+
tx.collectFrom([cdpCreatorUtxo], {
|
|
279
|
+
kind: 'self',
|
|
280
|
+
makeRedeemer: (inputIdx) => {
|
|
281
|
+
return serialiseCDPCreatorRedeemer({
|
|
282
|
+
CreateCDP: {
|
|
283
|
+
cdpOwner: fromHex(pkh.hash),
|
|
284
|
+
minted: mintedAmount,
|
|
285
|
+
collateralAmt: collateralAmount,
|
|
286
|
+
currentTime: currentTime,
|
|
287
|
+
creatorInputIdx: inputIdx,
|
|
288
|
+
creatorOutputIdx: 1n,
|
|
289
|
+
cdpOutputIdx: 0n,
|
|
290
|
+
iassetRefInputIdx: refInputsIndices[1],
|
|
291
|
+
collateralAssetRefInputIdx: refInputsIndices[2],
|
|
292
|
+
interestOracleRefInputIdx: refInputsIndices[0],
|
|
293
|
+
priceOracleIdx:
|
|
294
|
+
priceOracleOref !== undefined
|
|
295
|
+
? { OracleRefInputIdx: refInputsIndices[3] }
|
|
296
|
+
: 'OracleVoid',
|
|
297
|
+
},
|
|
298
|
+
});
|
|
299
|
+
},
|
|
300
|
+
});
|
|
223
301
|
|
|
224
302
|
return tx;
|
|
225
303
|
}
|
|
226
304
|
|
|
227
|
-
async function adjustCdp(
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
305
|
+
export async function adjustCdp(
|
|
306
|
+
collateralAdjustment: bigint,
|
|
307
|
+
debtAdjustment: bigint,
|
|
308
|
+
cdpOref: OutRef,
|
|
309
|
+
iassetOref: OutRef,
|
|
310
|
+
collateralAssetOref: OutRef,
|
|
311
|
+
priceOracleOref: OutRef | undefined,
|
|
312
|
+
interestOracleOref: OutRef,
|
|
313
|
+
treasuryOref: OutRef,
|
|
314
|
+
interestCollectorOref: OutRef,
|
|
237
315
|
sysParams: SystemParams,
|
|
238
316
|
lucid: LucidEvolution,
|
|
239
317
|
currentSlot: number,
|
|
318
|
+
pythMessage: string | undefined = undefined,
|
|
319
|
+
pythStateOref: OutRef | undefined = undefined,
|
|
240
320
|
): Promise<TxBuilder> {
|
|
241
321
|
const network = lucid.config().network!;
|
|
242
322
|
const currentTime = BigInt(slotToUnixTime(network, currentSlot));
|
|
@@ -248,97 +328,178 @@ async function adjustCdp(
|
|
|
248
328
|
(_) => new Error('Expected a single cdp Ref Script UTXO'),
|
|
249
329
|
);
|
|
250
330
|
|
|
251
|
-
const cdpUtxo =
|
|
331
|
+
const cdpUtxo = matchSingle(
|
|
332
|
+
await lucid.utxosByOutRef([cdpOref]),
|
|
333
|
+
(_) => new Error('Expected a single cdp UTXO'),
|
|
334
|
+
);
|
|
252
335
|
const cdpDatum = parseCdpDatumOrThrow(getInlineDatumOrThrow(cdpUtxo));
|
|
253
336
|
|
|
254
|
-
const iassetUtxo =
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
'Expected a single iasset UTXO',
|
|
337
|
+
const iassetUtxo = matchSingle(
|
|
338
|
+
await lucid.utxosByOutRef([iassetOref]),
|
|
339
|
+
(_) => new Error('Expected a single iasset UTXO'),
|
|
258
340
|
);
|
|
341
|
+
|
|
259
342
|
const iassetDatum = parseIAssetDatumOrThrow(
|
|
260
343
|
getInlineDatumOrThrow(iassetUtxo),
|
|
261
344
|
);
|
|
262
345
|
|
|
263
|
-
const
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
const priceOracleUtxo = await resolveUtxo(
|
|
267
|
-
priceOracle,
|
|
268
|
-
lucid,
|
|
269
|
-
'Expected a single price oracle UTXO',
|
|
346
|
+
const collateralAssetUtxo = matchSingle(
|
|
347
|
+
await lucid.utxosByOutRef([collateralAssetOref]),
|
|
348
|
+
(_) => new Error('Expected a single collateral asset UTXO'),
|
|
270
349
|
);
|
|
271
|
-
const
|
|
272
|
-
getInlineDatumOrThrow(
|
|
350
|
+
const collateralAssetDatum = parseCollateralAssetDatumOrThrow(
|
|
351
|
+
getInlineDatumOrThrow(collateralAssetUtxo),
|
|
273
352
|
);
|
|
274
353
|
|
|
275
|
-
const
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
354
|
+
const iAssetAc = {
|
|
355
|
+
currencySymbol: fromHex(
|
|
356
|
+
sysParams.cdpParams.cdpAssetSymbol.unCurrencySymbol,
|
|
357
|
+
),
|
|
358
|
+
tokenName: iassetDatum.assetName,
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
const isMintOrWithdraw = debtAdjustment > 0n || collateralAdjustment < 0n;
|
|
362
|
+
|
|
363
|
+
const interestOracleUtxo = matchSingle(
|
|
364
|
+
await lucid.utxosByOutRef([interestOracleOref]),
|
|
365
|
+
(_) => new Error('Expected a single interest oracle UTXO'),
|
|
279
366
|
);
|
|
280
367
|
const interestOracleDatum = parseInterestOracleDatum(
|
|
281
368
|
getInlineDatumOrThrow(interestOracleUtxo),
|
|
282
369
|
);
|
|
283
370
|
|
|
284
|
-
match(
|
|
285
|
-
.with({ Delisted: P.any }, () => {
|
|
286
|
-
throw new Error("Can't adjust CDP of delisted asset");
|
|
287
|
-
})
|
|
288
|
-
.otherwise(() => {});
|
|
289
|
-
|
|
290
|
-
const txValidity = oracleExpirationAwareValidity(
|
|
291
|
-
currentSlot,
|
|
292
|
-
Number(sysParams.cdpCreatorParams.biasTime),
|
|
293
|
-
Number(priceOracleDatum.expiration),
|
|
294
|
-
network,
|
|
295
|
-
);
|
|
296
|
-
|
|
297
|
-
const interestAdaAmt = match(cdpDatum.cdpFees)
|
|
371
|
+
const interestAmt = match(cdpDatum.cdpFees)
|
|
298
372
|
.with({ FrozenCDPAccumulatedFees: P.any }, () => {
|
|
299
373
|
throw new Error('CDP fees wrong');
|
|
300
374
|
})
|
|
301
375
|
.with({ ActiveCDPInterestTracking: P.select() }, (interest) => {
|
|
302
|
-
|
|
376
|
+
return calculateAccruedInterest(
|
|
303
377
|
currentTime,
|
|
304
378
|
interest.unitaryInterestSnapshot,
|
|
305
379
|
cdpDatum.mintedAmt,
|
|
306
380
|
interest.lastSettled,
|
|
307
381
|
interestOracleDatum,
|
|
308
382
|
);
|
|
309
|
-
|
|
310
|
-
return (
|
|
311
|
-
(interestPaymentIAssetAmt * priceOracleDatum.price.getOnChainInt) /
|
|
312
|
-
1_000_000n
|
|
313
|
-
);
|
|
314
383
|
})
|
|
315
384
|
.exhaustive();
|
|
316
385
|
|
|
317
|
-
const
|
|
386
|
+
const mintedAmountChange = debtAdjustment + interestAmt;
|
|
318
387
|
|
|
319
|
-
const
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
388
|
+
const referenceScripts = [cdpRefScriptUtxo];
|
|
389
|
+
let referenceInputs = [iassetUtxo, collateralAssetUtxo, interestOracleUtxo];
|
|
390
|
+
|
|
391
|
+
let treasuryFee = 0n;
|
|
392
|
+
|
|
393
|
+
const tx = lucid.newTx().readFrom(referenceScripts);
|
|
394
|
+
|
|
395
|
+
if (isMintOrWithdraw) {
|
|
396
|
+
const { interval, referenceInputs: oracleRefInputs } = await attachOracle(
|
|
397
|
+
iassetDatum.assetName,
|
|
398
|
+
collateralAssetDatum.collateralAsset,
|
|
399
|
+
collateralAssetDatum.priceInfo,
|
|
400
|
+
priceOracleOref,
|
|
401
|
+
pythStateOref,
|
|
402
|
+
pythMessage,
|
|
403
|
+
sysParams.pythConfig,
|
|
404
|
+
sysParams.cdpParams.biasTime,
|
|
405
|
+
currentSlot,
|
|
406
|
+
lucid,
|
|
407
|
+
tx,
|
|
408
|
+
);
|
|
409
|
+
|
|
410
|
+
referenceInputs = [...oracleRefInputs, ...referenceInputs];
|
|
411
|
+
|
|
412
|
+
// Set the validity interval for the transaction
|
|
413
|
+
tx.validFrom(interval.validFrom).validTo(interval.validTo);
|
|
414
|
+
} else {
|
|
415
|
+
// Set the validity interval for the transaction
|
|
416
|
+
tx.validFrom(
|
|
417
|
+
Number(currentTime - BigInt(sysParams.cdpParams.biasTime) / 2n),
|
|
418
|
+
).validTo(Number(currentTime + BigInt(sysParams.cdpParams.biasTime) / 2n));
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// when mint
|
|
422
|
+
if (debtAdjustment > 0n) {
|
|
423
|
+
treasuryFee += calculateFeeFromRatio(
|
|
424
|
+
iassetDatum.debtMintingFeeRatio,
|
|
425
|
+
debtAdjustment,
|
|
426
|
+
);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
const treasuryRefScriptUtxo =
|
|
430
|
+
treasuryFee > 0
|
|
431
|
+
? await treasuryFeeTx(
|
|
432
|
+
iAssetAc,
|
|
433
|
+
treasuryFee,
|
|
434
|
+
0n,
|
|
435
|
+
lucid,
|
|
436
|
+
sysParams,
|
|
437
|
+
tx,
|
|
438
|
+
cdpUtxo,
|
|
439
|
+
treasuryOref,
|
|
440
|
+
)
|
|
441
|
+
: undefined;
|
|
442
|
+
|
|
443
|
+
const interestCollectorRefScriptUtxo =
|
|
444
|
+
interestAmt > 0n
|
|
445
|
+
? await collectInterestTx(
|
|
446
|
+
mkAssetsOf(iAssetAc, interestAmt),
|
|
447
|
+
lucid,
|
|
448
|
+
sysParams,
|
|
449
|
+
tx,
|
|
450
|
+
interestCollectorOref,
|
|
451
|
+
)
|
|
452
|
+
: undefined;
|
|
453
|
+
|
|
454
|
+
const iAssetTokenPolicyRefScriptUtxo =
|
|
455
|
+
mintedAmountChange !== 0n
|
|
456
|
+
? matchSingle(
|
|
457
|
+
await lucid.utxosByOutRef([
|
|
458
|
+
fromSystemParamsScriptRef(
|
|
459
|
+
sysParams.scriptReferences.iAssetTokenPolicyRef,
|
|
460
|
+
),
|
|
461
|
+
]),
|
|
462
|
+
(_) =>
|
|
463
|
+
new Error('Expected a single iasset token policy Ref Script UTXO'),
|
|
464
|
+
)
|
|
465
|
+
: undefined;
|
|
466
|
+
|
|
467
|
+
// We need to take into account the treasury, interest collector
|
|
468
|
+
// and iAsset policy ref scripts as well.
|
|
469
|
+
const refInputsIndices = getInputIndices(referenceInputs, [
|
|
470
|
+
...referenceInputs,
|
|
471
|
+
...referenceScripts,
|
|
472
|
+
...(treasuryRefScriptUtxo != null ? [treasuryRefScriptUtxo] : []),
|
|
473
|
+
...(interestCollectorRefScriptUtxo != null
|
|
474
|
+
? [interestCollectorRefScriptUtxo]
|
|
475
|
+
: []),
|
|
476
|
+
...(iAssetTokenPolicyRefScriptUtxo != null
|
|
477
|
+
? [iAssetTokenPolicyRefScriptUtxo]
|
|
478
|
+
: []),
|
|
479
|
+
]);
|
|
480
|
+
|
|
481
|
+
tx.readFrom(referenceInputs)
|
|
323
482
|
.collectFrom(
|
|
324
483
|
[cdpUtxo],
|
|
325
484
|
serialiseCdpRedeemer({
|
|
326
485
|
AdjustCdp: {
|
|
327
|
-
collateralAmtChange: collateralAmount,
|
|
328
486
|
currentTime: currentTime,
|
|
329
|
-
|
|
487
|
+
debtAdjustment: debtAdjustment,
|
|
488
|
+
collateralAdjustment,
|
|
489
|
+
priceOracleIdx:
|
|
490
|
+
priceOracleOref !== undefined
|
|
491
|
+
? { OracleRefInputIdx: refInputsIndices[0] }
|
|
492
|
+
: 'OracleVoid',
|
|
330
493
|
},
|
|
331
494
|
}),
|
|
332
495
|
)
|
|
333
|
-
.readFrom([cdpRefScriptUtxo])
|
|
334
|
-
.readFrom([iassetUtxo, govUtxo, priceOracleUtxo, interestOracleUtxo])
|
|
335
496
|
.pay.ToContract(
|
|
336
497
|
cdpUtxo.address,
|
|
337
498
|
{
|
|
338
499
|
kind: 'inline',
|
|
339
500
|
value: serialiseCdpDatum({
|
|
340
501
|
...cdpDatum,
|
|
341
|
-
mintedAmt: cdpDatum.mintedAmt +
|
|
502
|
+
mintedAmt: cdpDatum.mintedAmt + mintedAmountChange,
|
|
342
503
|
cdpFees: {
|
|
343
504
|
ActiveCDPInterestTracking: {
|
|
344
505
|
lastSettled: currentTime,
|
|
@@ -351,83 +512,38 @@ async function adjustCdp(
|
|
|
351
512
|
},
|
|
352
513
|
}),
|
|
353
514
|
},
|
|
354
|
-
addAssets(
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
throw new Error('Expected active CDP');
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
tx.addSignerKey(cdpDatum.cdpOwner);
|
|
362
|
-
|
|
363
|
-
if (mintAmount !== 0n) {
|
|
364
|
-
const iAssetTokenPolicyRefScriptUtxo = matchSingle(
|
|
365
|
-
await lucid.utxosByOutRef([
|
|
366
|
-
fromSystemParamsScriptRef(
|
|
367
|
-
sysParams.scriptReferences.iAssetTokenPolicyRef,
|
|
368
|
-
),
|
|
369
|
-
]),
|
|
370
|
-
(_) => new Error('Expected a single iasset token policy Ref Script UTXO'),
|
|
515
|
+
addAssets(
|
|
516
|
+
cdpUtxo.assets,
|
|
517
|
+
mkAssetsOf(cdpDatum.collateralAsset, collateralAdjustment),
|
|
518
|
+
),
|
|
371
519
|
);
|
|
372
520
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
currencySymbol: sysParams.cdpParams.cdpAssetSymbol.unCurrencySymbol,
|
|
376
|
-
tokenName: iassetDatum.assetName,
|
|
377
|
-
},
|
|
378
|
-
mintAmount,
|
|
379
|
-
);
|
|
521
|
+
if (mintedAmountChange !== 0n) {
|
|
522
|
+
const iassetTokensVal = mkAssetsOf(iAssetAc, mintedAmountChange);
|
|
380
523
|
|
|
381
|
-
tx.readFrom([iAssetTokenPolicyRefScriptUtxo]).mintAssets(
|
|
524
|
+
tx.readFrom([iAssetTokenPolicyRefScriptUtxo as UTxO]).mintAssets(
|
|
382
525
|
iassetTokensVal,
|
|
383
526
|
Data.void(),
|
|
384
527
|
);
|
|
385
528
|
}
|
|
386
529
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
interestAdaAmt,
|
|
390
|
-
);
|
|
391
|
-
const interestTreasuryAdaAmt = interestAdaAmt - interestCollectorAdaAmt;
|
|
392
|
-
|
|
393
|
-
if (interestTreasuryAdaAmt > 0) {
|
|
394
|
-
await treasuryFeeTx(interestTreasuryAdaAmt, lucid, sysParams, tx, treasury);
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
let collectorFee = interestCollectorAdaAmt;
|
|
398
|
-
|
|
399
|
-
// when mint
|
|
400
|
-
if (mintAmount > 0n) {
|
|
401
|
-
collectorFee += calculateFeeFromPercentage(
|
|
402
|
-
iassetDatum.debtMintingFeePercentage,
|
|
403
|
-
(mintAmount * priceOracleDatum.price.getOnChainInt) / 1_000_000n,
|
|
404
|
-
);
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
// when withdraw
|
|
408
|
-
if (collateralAmount < 0n) {
|
|
409
|
-
collectorFee += calculateFeeFromPercentage(
|
|
410
|
-
govDatum.protocolParams.collateralFeePercentage,
|
|
411
|
-
-collateralAmount,
|
|
412
|
-
);
|
|
530
|
+
if (!cdpDatum.cdpOwner) {
|
|
531
|
+
throw new Error('Expected active CDP');
|
|
413
532
|
}
|
|
414
533
|
|
|
415
|
-
|
|
416
|
-
await collectorFeeTx(collectorFee, lucid, sysParams, tx, collector);
|
|
417
|
-
}
|
|
534
|
+
tx.addSignerKey(toHex(cdpDatum.cdpOwner));
|
|
418
535
|
|
|
419
536
|
return tx;
|
|
420
537
|
}
|
|
421
538
|
|
|
422
539
|
export async function depositCdp(
|
|
423
540
|
amount: bigint,
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
treasury: UtxoOrOutRef,
|
|
541
|
+
cdpOref: OutRef,
|
|
542
|
+
iassetOref: OutRef,
|
|
543
|
+
collateralAssetOref: OutRef,
|
|
544
|
+
interestOracleOref: OutRef,
|
|
545
|
+
treasuryOref: OutRef,
|
|
546
|
+
interestCollectorOref: OutRef,
|
|
431
547
|
params: SystemParams,
|
|
432
548
|
lucid: LucidEvolution,
|
|
433
549
|
currentSlot: number,
|
|
@@ -435,13 +551,13 @@ export async function depositCdp(
|
|
|
435
551
|
return adjustCdp(
|
|
436
552
|
amount,
|
|
437
553
|
0n,
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
554
|
+
cdpOref,
|
|
555
|
+
iassetOref,
|
|
556
|
+
collateralAssetOref,
|
|
557
|
+
undefined,
|
|
558
|
+
interestOracleOref,
|
|
559
|
+
treasuryOref,
|
|
560
|
+
interestCollectorOref,
|
|
445
561
|
params,
|
|
446
562
|
lucid,
|
|
447
563
|
currentSlot,
|
|
@@ -450,71 +566,78 @@ export async function depositCdp(
|
|
|
450
566
|
|
|
451
567
|
export async function withdrawCdp(
|
|
452
568
|
amount: bigint,
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
569
|
+
cdpOref: OutRef,
|
|
570
|
+
iassetOref: OutRef,
|
|
571
|
+
collateralAssetOref: OutRef,
|
|
572
|
+
priceOracleOref: OutRef | undefined,
|
|
573
|
+
interestOracleOref: OutRef,
|
|
574
|
+
treasuryOref: OutRef,
|
|
575
|
+
interestCollectorOref: OutRef,
|
|
460
576
|
params: SystemParams,
|
|
461
577
|
lucid: LucidEvolution,
|
|
462
578
|
currentSlot: number,
|
|
579
|
+
pythMessage: string | undefined = undefined,
|
|
580
|
+
pythStateOref: OutRef | undefined = undefined,
|
|
463
581
|
): Promise<TxBuilder> {
|
|
464
582
|
return adjustCdp(
|
|
465
583
|
-amount,
|
|
466
584
|
0n,
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
585
|
+
cdpOref,
|
|
586
|
+
iassetOref,
|
|
587
|
+
collateralAssetOref,
|
|
588
|
+
priceOracleOref,
|
|
589
|
+
interestOracleOref,
|
|
590
|
+
treasuryOref,
|
|
591
|
+
interestCollectorOref,
|
|
474
592
|
params,
|
|
475
593
|
lucid,
|
|
476
594
|
currentSlot,
|
|
595
|
+
pythMessage,
|
|
596
|
+
pythStateOref,
|
|
477
597
|
);
|
|
478
598
|
}
|
|
479
599
|
|
|
480
600
|
export async function mintCdp(
|
|
481
601
|
amount: bigint,
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
602
|
+
cdpOref: OutRef,
|
|
603
|
+
iassetOref: OutRef,
|
|
604
|
+
collateralAssetOref: OutRef,
|
|
605
|
+
priceOracleOref: OutRef | undefined,
|
|
606
|
+
interestOracleOref: OutRef,
|
|
607
|
+
treasuryOref: OutRef,
|
|
608
|
+
interestCollectorOref: OutRef,
|
|
489
609
|
params: SystemParams,
|
|
490
610
|
lucid: LucidEvolution,
|
|
491
611
|
currentSlot: number,
|
|
612
|
+
pythMessage: string | undefined = undefined,
|
|
613
|
+
pythStateOref: OutRef | undefined = undefined,
|
|
492
614
|
): Promise<TxBuilder> {
|
|
493
615
|
return adjustCdp(
|
|
494
616
|
0n,
|
|
495
617
|
amount,
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
618
|
+
cdpOref,
|
|
619
|
+
iassetOref,
|
|
620
|
+
collateralAssetOref,
|
|
621
|
+
priceOracleOref,
|
|
622
|
+
interestOracleOref,
|
|
623
|
+
treasuryOref,
|
|
624
|
+
interestCollectorOref,
|
|
503
625
|
params,
|
|
504
626
|
lucid,
|
|
505
627
|
currentSlot,
|
|
628
|
+
pythMessage,
|
|
629
|
+
pythStateOref,
|
|
506
630
|
);
|
|
507
631
|
}
|
|
508
632
|
|
|
509
633
|
export async function burnCdp(
|
|
510
634
|
amount: bigint,
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
treasury: UtxoOrOutRef,
|
|
635
|
+
cdpOref: OutRef,
|
|
636
|
+
iassetOref: OutRef,
|
|
637
|
+
collateralAssetOref: OutRef,
|
|
638
|
+
interestOracleOref: OutRef,
|
|
639
|
+
treasuryOref: OutRef,
|
|
640
|
+
interestCollectorOref: OutRef,
|
|
518
641
|
params: SystemParams,
|
|
519
642
|
lucid: LucidEvolution,
|
|
520
643
|
currentSlot: number,
|
|
@@ -522,13 +645,13 @@ export async function burnCdp(
|
|
|
522
645
|
return adjustCdp(
|
|
523
646
|
0n,
|
|
524
647
|
-amount,
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
648
|
+
cdpOref,
|
|
649
|
+
iassetOref,
|
|
650
|
+
collateralAssetOref,
|
|
651
|
+
undefined,
|
|
652
|
+
interestOracleOref,
|
|
653
|
+
treasuryOref,
|
|
654
|
+
interestCollectorOref,
|
|
532
655
|
params,
|
|
533
656
|
lucid,
|
|
534
657
|
currentSlot,
|
|
@@ -536,13 +659,10 @@ export async function burnCdp(
|
|
|
536
659
|
}
|
|
537
660
|
|
|
538
661
|
export async function closeCdp(
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
collector: UtxoOrOutRef,
|
|
544
|
-
gov: UtxoOrOutRef,
|
|
545
|
-
treasury: UtxoOrOutRef,
|
|
662
|
+
cdpOref: OutRef,
|
|
663
|
+
collateralAssetOref: OutRef,
|
|
664
|
+
interestOracleOref: OutRef,
|
|
665
|
+
interestCollectorOref: OutRef,
|
|
546
666
|
sysParams: SystemParams,
|
|
547
667
|
lucid: LucidEvolution,
|
|
548
668
|
currentSlot: number,
|
|
@@ -575,45 +695,30 @@ export async function closeCdp(
|
|
|
575
695
|
(_) => new Error('Expected a single iasset token policy Ref Script UTXO'),
|
|
576
696
|
);
|
|
577
697
|
|
|
578
|
-
const cdpUtxo =
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
const iassetUtxo = await resolveUtxo(
|
|
582
|
-
iasset,
|
|
583
|
-
lucid,
|
|
584
|
-
'Expected a single iasset UTXO',
|
|
698
|
+
const cdpUtxo = matchSingle(
|
|
699
|
+
await lucid.utxosByOutRef([cdpOref]),
|
|
700
|
+
(_) => new Error('Expected a single cdp UTXO'),
|
|
585
701
|
);
|
|
586
|
-
const
|
|
587
|
-
getInlineDatumOrThrow(iassetUtxo),
|
|
588
|
-
);
|
|
589
|
-
|
|
590
|
-
const govUtxo = await resolveUtxo(gov, lucid, 'Expected a single gov UTXO');
|
|
591
|
-
const govDatum = parseGovDatumOrThrow(getInlineDatumOrThrow(govUtxo));
|
|
702
|
+
const cdpDatum = parseCdpDatumOrThrow(getInlineDatumOrThrow(cdpUtxo));
|
|
592
703
|
|
|
593
|
-
const
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
'Expected a single price oracle UTXO',
|
|
704
|
+
const collateralAssetUtxo = matchSingle(
|
|
705
|
+
await lucid.utxosByOutRef([collateralAssetOref]),
|
|
706
|
+
(_) => new Error('Expected a single collateral asset UTXO'),
|
|
597
707
|
);
|
|
598
|
-
const
|
|
599
|
-
getInlineDatumOrThrow(
|
|
708
|
+
const collateralDatum = parseCollateralAssetDatumOrThrow(
|
|
709
|
+
getInlineDatumOrThrow(collateralAssetUtxo),
|
|
600
710
|
);
|
|
601
711
|
|
|
602
|
-
const interestOracleUtxo =
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
'Expected a single interest oracle UTXO',
|
|
712
|
+
const interestOracleUtxo = matchSingle(
|
|
713
|
+
await lucid.utxosByOutRef([interestOracleOref]),
|
|
714
|
+
(_) => new Error('Expected a single interest oracle UTXO'),
|
|
606
715
|
);
|
|
607
716
|
const interestOracleDatum = parseInterestOracleDatum(
|
|
608
717
|
getInlineDatumOrThrow(interestOracleUtxo),
|
|
609
718
|
);
|
|
610
719
|
|
|
611
|
-
const
|
|
612
|
-
|
|
613
|
-
Number(sysParams.cdpCreatorParams.biasTime),
|
|
614
|
-
Number(priceOracleDatum.expiration),
|
|
615
|
-
network,
|
|
616
|
-
);
|
|
720
|
+
const validateFrom = slotToUnixTime(network, currentSlot - 1);
|
|
721
|
+
const validateTo = validateFrom + Number(sysParams.cdpCreatorParams.biasTime);
|
|
617
722
|
|
|
618
723
|
const tx = lucid
|
|
619
724
|
.newTx()
|
|
@@ -622,14 +727,16 @@ export async function closeCdp(
|
|
|
622
727
|
iAssetTokenPolicyRefScriptUtxo,
|
|
623
728
|
cdpAuthTokenPolicyRefScriptUtxo,
|
|
624
729
|
])
|
|
625
|
-
.readFrom([
|
|
626
|
-
.validFrom(
|
|
627
|
-
.validTo(
|
|
730
|
+
.readFrom([collateralAssetUtxo, interestOracleUtxo])
|
|
731
|
+
.validFrom(validateFrom)
|
|
732
|
+
.validTo(validateTo)
|
|
628
733
|
.mintAssets(
|
|
629
734
|
mkAssetsOf(
|
|
630
735
|
{
|
|
631
|
-
currencySymbol:
|
|
632
|
-
|
|
736
|
+
currencySymbol: fromHex(
|
|
737
|
+
sysParams.cdpParams.cdpAssetSymbol.unCurrencySymbol,
|
|
738
|
+
),
|
|
739
|
+
tokenName: collateralDatum.iasset,
|
|
633
740
|
},
|
|
634
741
|
-cdpDatum.mintedAmt,
|
|
635
742
|
),
|
|
@@ -648,47 +755,39 @@ export async function closeCdp(
|
|
|
648
755
|
throw new Error('Expected active CDP');
|
|
649
756
|
}
|
|
650
757
|
|
|
651
|
-
tx.addSignerKey(cdpDatum.cdpOwner);
|
|
758
|
+
tx.addSignerKey(toHex(cdpDatum.cdpOwner));
|
|
652
759
|
|
|
653
|
-
const
|
|
760
|
+
const interestAmt = match(cdpDatum.cdpFees)
|
|
654
761
|
.with({ FrozenCDPAccumulatedFees: P.any }, () => {
|
|
655
762
|
throw new Error('CDP fees wrong');
|
|
656
763
|
})
|
|
657
764
|
.with({ ActiveCDPInterestTracking: P.select() }, (interest) => {
|
|
658
|
-
|
|
765
|
+
return calculateAccruedInterest(
|
|
659
766
|
currentTime,
|
|
660
767
|
interest.unitaryInterestSnapshot,
|
|
661
768
|
cdpDatum.mintedAmt,
|
|
662
769
|
interest.lastSettled,
|
|
663
770
|
interestOracleDatum,
|
|
664
771
|
);
|
|
665
|
-
|
|
666
|
-
return (
|
|
667
|
-
(interestPaymentIAssetAmt * priceOracleDatum.price.getOnChainInt) /
|
|
668
|
-
1_000_000n
|
|
669
|
-
);
|
|
670
772
|
})
|
|
671
773
|
.exhaustive();
|
|
672
774
|
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
775
|
+
if (interestAmt > 0n) {
|
|
776
|
+
await collectInterestTx(
|
|
777
|
+
mkAssetsOf(
|
|
778
|
+
{
|
|
779
|
+
currencySymbol: fromHex(
|
|
780
|
+
sysParams.cdpParams.cdpAssetSymbol.unCurrencySymbol,
|
|
781
|
+
),
|
|
782
|
+
tokenName: collateralDatum.iasset,
|
|
783
|
+
},
|
|
784
|
+
interestAmt,
|
|
785
|
+
),
|
|
786
|
+
lucid,
|
|
787
|
+
sysParams,
|
|
788
|
+
tx,
|
|
789
|
+
interestCollectorOref,
|
|
688
790
|
);
|
|
689
|
-
|
|
690
|
-
if (collectorFee > 0n) {
|
|
691
|
-
await collectorFeeTx(collectorFee, lucid, sysParams, tx, collector);
|
|
692
791
|
}
|
|
693
792
|
|
|
694
793
|
return tx;
|
|
@@ -700,15 +799,19 @@ export async function redeemCdp(
|
|
|
700
799
|
* The logic will automatically cap the amount to the max.
|
|
701
800
|
*/
|
|
702
801
|
attemptedRedemptionIAssetAmt: bigint,
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
802
|
+
cdpOref: OutRef,
|
|
803
|
+
iassetOref: OutRef,
|
|
804
|
+
collateralAssetOref: OutRef,
|
|
805
|
+
priceOracleOref: OutRef | undefined,
|
|
806
|
+
interestOracleOref: OutRef,
|
|
807
|
+
interestCollectorOref: OutRef,
|
|
808
|
+
treasuryOref: OutRef,
|
|
809
|
+
govOref: OutRef,
|
|
709
810
|
sysParams: SystemParams,
|
|
710
811
|
lucid: LucidEvolution,
|
|
711
812
|
currentSlot: number,
|
|
813
|
+
pythMessage: string | undefined = undefined,
|
|
814
|
+
_pythStateOref: OutRef | undefined = undefined,
|
|
712
815
|
): Promise<TxBuilder> {
|
|
713
816
|
const network = lucid.config().network!;
|
|
714
817
|
const currentTime = BigInt(slotToUnixTime(network, currentSlot));
|
|
@@ -720,6 +823,15 @@ export async function redeemCdp(
|
|
|
720
823
|
(_) => new Error('Expected a single cdp Ref Script UTXO'),
|
|
721
824
|
);
|
|
722
825
|
|
|
826
|
+
const cdpRedeemRefScriptUtxo = matchSingle(
|
|
827
|
+
await lucid.utxosByOutRef([
|
|
828
|
+
fromSystemParamsScriptRef(
|
|
829
|
+
sysParams.scriptReferences.cdpRedeemValidatorRef,
|
|
830
|
+
),
|
|
831
|
+
]),
|
|
832
|
+
(_) => new Error('Expected a single cdp redeem Ref Script UTXO'),
|
|
833
|
+
);
|
|
834
|
+
|
|
723
835
|
const iAssetTokenPolicyRefScriptUtxo = matchSingle(
|
|
724
836
|
await lucid.utxosByOutRef([
|
|
725
837
|
fromSystemParamsScriptRef(
|
|
@@ -729,73 +841,91 @@ export async function redeemCdp(
|
|
|
729
841
|
(_) => new Error('Expected a single iasset token policy Ref Script UTXO'),
|
|
730
842
|
);
|
|
731
843
|
|
|
732
|
-
const cdpUtxo =
|
|
844
|
+
const cdpUtxo = matchSingle(
|
|
845
|
+
await lucid.utxosByOutRef([cdpOref]),
|
|
846
|
+
(_) => new Error('Expected a single cdp UTXO'),
|
|
847
|
+
);
|
|
733
848
|
const cdpDatum = parseCdpDatumOrThrow(getInlineDatumOrThrow(cdpUtxo));
|
|
734
849
|
|
|
735
|
-
const iassetUtxo =
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
'Expected a single iasset UTXO',
|
|
850
|
+
const iassetUtxo = matchSingle(
|
|
851
|
+
await lucid.utxosByOutRef([iassetOref]),
|
|
852
|
+
(_) => new Error('Expected a single iasset UTXO'),
|
|
739
853
|
);
|
|
740
854
|
const iassetDatum = parseIAssetDatumOrThrow(
|
|
741
855
|
getInlineDatumOrThrow(iassetUtxo),
|
|
742
856
|
);
|
|
743
857
|
|
|
744
|
-
const
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
'Expected a single price oracle UTXO',
|
|
858
|
+
const collateralAssetUtxo = matchSingle(
|
|
859
|
+
await lucid.utxosByOutRef([collateralAssetOref]),
|
|
860
|
+
(_) => new Error('Expected a single collateral asset UTXO'),
|
|
748
861
|
);
|
|
749
|
-
const
|
|
750
|
-
getInlineDatumOrThrow(
|
|
862
|
+
const collateralAssetDatum = parseCollateralAssetDatumOrThrow(
|
|
863
|
+
getInlineDatumOrThrow(collateralAssetUtxo),
|
|
751
864
|
);
|
|
752
865
|
|
|
753
|
-
const
|
|
754
|
-
|
|
866
|
+
const isDelisted = match(collateralAssetDatum.priceInfo)
|
|
867
|
+
.with({ Delisted: P.any }, () => true)
|
|
868
|
+
.otherwise(() => false);
|
|
869
|
+
|
|
870
|
+
if (!isDelisted && priceOracleOref === undefined) {
|
|
871
|
+
throw new Error('Missing price oracle');
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
const [adjustedPrice, priceOracleUtxo] = await retrieveAdjustedPrice(
|
|
875
|
+
iassetDatum.assetName,
|
|
876
|
+
collateralAssetDatum.collateralAsset,
|
|
877
|
+
collateralAssetDatum.priceInfo,
|
|
878
|
+
collateralAssetDatum.extraDecimals,
|
|
879
|
+
priceOracleOref,
|
|
880
|
+
pythMessage,
|
|
881
|
+
sysParams.pythConfig,
|
|
755
882
|
lucid,
|
|
756
|
-
|
|
883
|
+
);
|
|
884
|
+
|
|
885
|
+
const interestOracleUtxo = matchSingle(
|
|
886
|
+
await lucid.utxosByOutRef([interestOracleOref]),
|
|
887
|
+
(_) => new Error('Expected a single interest oracle UTXO'),
|
|
757
888
|
);
|
|
758
889
|
const interestOracleDatum = parseInterestOracleDatum(
|
|
759
890
|
getInlineDatumOrThrow(interestOracleUtxo),
|
|
760
891
|
);
|
|
761
892
|
|
|
762
|
-
const
|
|
893
|
+
const govUtxo = matchSingle(
|
|
894
|
+
await lucid.utxosByOutRef([govOref]),
|
|
895
|
+
(_) => new Error('Expected a single gov UTXO'),
|
|
896
|
+
);
|
|
897
|
+
const govDatum = parseGovDatumOrThrow(getInlineDatumOrThrow(govUtxo));
|
|
898
|
+
|
|
899
|
+
const interestAmt = match(cdpDatum.cdpFees)
|
|
763
900
|
.with({ FrozenCDPAccumulatedFees: P.any }, () => {
|
|
764
901
|
throw new Error('CDP fees wrong');
|
|
765
902
|
})
|
|
766
903
|
.with({ ActiveCDPInterestTracking: P.select() }, (interest) => {
|
|
767
|
-
|
|
904
|
+
return calculateAccruedInterest(
|
|
768
905
|
currentTime,
|
|
769
906
|
interest.unitaryInterestSnapshot,
|
|
770
907
|
cdpDatum.mintedAmt,
|
|
771
908
|
interest.lastSettled,
|
|
772
909
|
interestOracleDatum,
|
|
773
910
|
);
|
|
774
|
-
|
|
775
|
-
return ocdMul(
|
|
776
|
-
{ getOnChainInt: interestPaymentIAssetAmt },
|
|
777
|
-
priceOracleDatum.price,
|
|
778
|
-
).getOnChainInt;
|
|
779
911
|
})
|
|
780
912
|
.exhaustive();
|
|
781
913
|
|
|
782
|
-
const
|
|
783
|
-
|
|
784
|
-
|
|
914
|
+
const collateralAmt = assetClassValueOf(
|
|
915
|
+
cdpUtxo.assets,
|
|
916
|
+
cdpDatum.collateralAsset,
|
|
785
917
|
);
|
|
786
|
-
const interestTreasuryAdaAmt = interestAdaAmt - interestCollectorAdaAmt;
|
|
787
918
|
|
|
788
|
-
const
|
|
789
|
-
lovelacesAmt(cdpUtxo.assets) - interestAdaAmt;
|
|
919
|
+
const totalCdpDebt = cdpDatum.mintedAmt + interestAmt;
|
|
790
920
|
|
|
791
921
|
const [isPartial, redemptionIAssetAmt] = (() => {
|
|
792
922
|
const res = calculateMinCollateralCappedIAssetRedemptionAmt(
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
iassetDatum.
|
|
798
|
-
BigInt(
|
|
923
|
+
collateralAmt,
|
|
924
|
+
totalCdpDebt,
|
|
925
|
+
adjustedPrice,
|
|
926
|
+
collateralAssetDatum.redemptionRatio,
|
|
927
|
+
iassetDatum.redemptionReimbursementRatio,
|
|
928
|
+
BigInt(collateralAssetDatum.minCollateralAmt),
|
|
799
929
|
);
|
|
800
930
|
|
|
801
931
|
const redemptionAmt = bigintMin(
|
|
@@ -810,50 +940,162 @@ export async function redeemCdp(
|
|
|
810
940
|
throw new Error("There's no iAssets available for redemption.");
|
|
811
941
|
}
|
|
812
942
|
|
|
813
|
-
const
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
const partialRedemptionFee = isPartial
|
|
818
|
-
? BigInt(sysParams.cdpParams.partialRedemptionExtraFeeLovelace)
|
|
819
|
-
: 0n;
|
|
943
|
+
const redemptionCollateralAmt = rationalFloor(
|
|
944
|
+
rationalMul(adjustedPrice, rationalFromInt(redemptionIAssetAmt)),
|
|
945
|
+
);
|
|
820
946
|
|
|
821
|
-
const processingFee =
|
|
822
|
-
iassetDatum.
|
|
823
|
-
|
|
947
|
+
const processingFee = calculateFeeFromRatio(
|
|
948
|
+
iassetDatum.redemptionProcessingFeeRatio,
|
|
949
|
+
redemptionCollateralAmt,
|
|
824
950
|
);
|
|
825
951
|
|
|
826
|
-
const reimburstmentFee =
|
|
827
|
-
iassetDatum.
|
|
828
|
-
|
|
952
|
+
const reimburstmentFee = calculateFeeFromRatio(
|
|
953
|
+
iassetDatum.redemptionReimbursementRatio,
|
|
954
|
+
redemptionCollateralAmt,
|
|
829
955
|
);
|
|
830
956
|
|
|
831
|
-
const
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
957
|
+
const referenceScripts = [
|
|
958
|
+
cdpRefScriptUtxo,
|
|
959
|
+
iAssetTokenPolicyRefScriptUtxo,
|
|
960
|
+
cdpRedeemRefScriptUtxo,
|
|
961
|
+
];
|
|
962
|
+
|
|
963
|
+
const referenceInputs = [
|
|
964
|
+
iassetUtxo,
|
|
965
|
+
collateralAssetUtxo,
|
|
966
|
+
interestOracleUtxo,
|
|
967
|
+
govUtxo,
|
|
968
|
+
];
|
|
969
|
+
|
|
970
|
+
const tx = lucid.newTx().readFrom(referenceScripts);
|
|
971
|
+
|
|
972
|
+
if (priceOracleUtxo !== undefined) {
|
|
973
|
+
const priceOracleDatum = parsePriceOracleDatum(
|
|
974
|
+
getInlineDatumOrThrow(priceOracleUtxo),
|
|
975
|
+
);
|
|
976
|
+
|
|
977
|
+
const txValidity = oracleExpirationAwareValidity(
|
|
978
|
+
currentSlot,
|
|
979
|
+
Number(sysParams.cdpCreatorParams.biasTime),
|
|
980
|
+
Number(priceOracleDatum.expirationTime),
|
|
981
|
+
network,
|
|
982
|
+
);
|
|
983
|
+
|
|
984
|
+
referenceInputs.push(priceOracleUtxo);
|
|
985
|
+
|
|
986
|
+
tx.validFrom(txValidity.validFrom).validTo(txValidity.validTo);
|
|
987
|
+
} else {
|
|
988
|
+
const validateFrom = slotToUnixTime(network, currentSlot - 1);
|
|
989
|
+
const validateTo =
|
|
990
|
+
validateFrom + Number(sysParams.cdpCreatorParams.biasTime);
|
|
991
|
+
|
|
992
|
+
tx.validFrom(validateFrom).validTo(validateTo);
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
const partialRedemptionFee = F.pipe(
|
|
996
|
+
govDatum.protocolParams.cdpRedemptionRequiredSignature,
|
|
997
|
+
O.fromNullable,
|
|
998
|
+
O.match(
|
|
999
|
+
// When public redemptions
|
|
1000
|
+
() => {
|
|
1001
|
+
return isPartial
|
|
1002
|
+
? BigInt(sysParams.cdpRedeemParams.partialRedemptionExtraFeeLovelace)
|
|
1003
|
+
: 0n;
|
|
1004
|
+
},
|
|
1005
|
+
// When private redemptions
|
|
1006
|
+
(requiredSignature) => {
|
|
1007
|
+
tx.addSignerKey(toHex(requiredSignature));
|
|
1008
|
+
return 0n;
|
|
1009
|
+
},
|
|
1010
|
+
),
|
|
836
1011
|
);
|
|
837
1012
|
|
|
838
|
-
const
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
1013
|
+
const treasuryRefScriptUtxo =
|
|
1014
|
+
processingFee > 0n
|
|
1015
|
+
? await treasuryFeeTx(
|
|
1016
|
+
cdpDatum.collateralAsset,
|
|
1017
|
+
processingFee,
|
|
1018
|
+
partialRedemptionFee,
|
|
1019
|
+
lucid,
|
|
1020
|
+
sysParams,
|
|
1021
|
+
tx,
|
|
1022
|
+
cdpOref,
|
|
1023
|
+
treasuryOref,
|
|
1024
|
+
)
|
|
1025
|
+
: partialRedemptionFee > 0n
|
|
1026
|
+
? await treasuryFeeTx(
|
|
1027
|
+
adaAssetClass,
|
|
1028
|
+
partialRedemptionFee,
|
|
1029
|
+
0n,
|
|
1030
|
+
lucid,
|
|
1031
|
+
sysParams,
|
|
1032
|
+
tx,
|
|
1033
|
+
cdpOref,
|
|
1034
|
+
treasuryOref,
|
|
1035
|
+
)
|
|
1036
|
+
: undefined;
|
|
1037
|
+
|
|
1038
|
+
const interestCollectorRefScriptUtxo =
|
|
1039
|
+
interestAmt > 0n
|
|
1040
|
+
? await collectInterestTx(
|
|
1041
|
+
mkAssetsOf(
|
|
1042
|
+
{
|
|
1043
|
+
currencySymbol: fromHex(
|
|
1044
|
+
sysParams.cdpParams.cdpAssetSymbol.unCurrencySymbol,
|
|
1045
|
+
),
|
|
1046
|
+
tokenName: iassetDatum.assetName,
|
|
1047
|
+
},
|
|
1048
|
+
interestAmt,
|
|
1049
|
+
),
|
|
1050
|
+
lucid,
|
|
1051
|
+
sysParams,
|
|
1052
|
+
tx,
|
|
1053
|
+
interestCollectorOref,
|
|
1054
|
+
)
|
|
1055
|
+
: undefined;
|
|
1056
|
+
|
|
1057
|
+
// We need to take into account the treasury and interest collector ref scripts as well.
|
|
1058
|
+
const refInputsIndices = getInputIndices(referenceInputs, [
|
|
1059
|
+
...referenceInputs,
|
|
1060
|
+
...referenceScripts,
|
|
1061
|
+
...(treasuryRefScriptUtxo != null ? [treasuryRefScriptUtxo] : []),
|
|
1062
|
+
...(interestCollectorRefScriptUtxo != null
|
|
1063
|
+
? [interestCollectorRefScriptUtxo]
|
|
1064
|
+
: []),
|
|
1065
|
+
]);
|
|
1066
|
+
|
|
1067
|
+
tx
|
|
842
1068
|
// Ref inputs
|
|
843
|
-
.readFrom(
|
|
844
|
-
|
|
845
|
-
.
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
1069
|
+
.readFrom(referenceInputs)
|
|
1070
|
+
// Trigger CDP Redeem Withdrawal validator
|
|
1071
|
+
.withdraw(
|
|
1072
|
+
credentialToRewardAddress(
|
|
1073
|
+
lucid.config().network!,
|
|
1074
|
+
scriptHashToCredential(sysParams.cdpParams.cdpRedeemValHash),
|
|
1075
|
+
),
|
|
1076
|
+
0n,
|
|
1077
|
+
serialiseRedeemCdpWithdrawalRedeemer({
|
|
1078
|
+
cdpOutReference: {
|
|
1079
|
+
txHash: fromHex(cdpUtxo.txHash),
|
|
1080
|
+
outputIndex: BigInt(cdpUtxo.outputIndex),
|
|
1081
|
+
},
|
|
1082
|
+
currentTime: currentTime,
|
|
1083
|
+
priceOracleIdx:
|
|
1084
|
+
priceOracleOref !== undefined
|
|
1085
|
+
? { OracleRefInputIdx: refInputsIndices[4] }
|
|
1086
|
+
: 'OracleVoid',
|
|
1087
|
+
}),
|
|
849
1088
|
)
|
|
1089
|
+
.collectFrom([cdpUtxo], serialiseCdpRedeemer('RedeemCdp'))
|
|
850
1090
|
.mintAssets(
|
|
851
1091
|
mkAssetsOf(
|
|
852
1092
|
{
|
|
853
|
-
currencySymbol:
|
|
1093
|
+
currencySymbol: fromHex(
|
|
1094
|
+
sysParams.cdpParams.cdpAssetSymbol.unCurrencySymbol,
|
|
1095
|
+
),
|
|
854
1096
|
tokenName: iassetDatum.assetName,
|
|
855
1097
|
},
|
|
856
|
-
-redemptionIAssetAmt,
|
|
1098
|
+
interestAmt - redemptionIAssetAmt,
|
|
857
1099
|
),
|
|
858
1100
|
Data.void(),
|
|
859
1101
|
)
|
|
@@ -863,7 +1105,7 @@ export async function redeemCdp(
|
|
|
863
1105
|
kind: 'inline',
|
|
864
1106
|
value: serialiseCdpDatum({
|
|
865
1107
|
...cdpDatum,
|
|
866
|
-
mintedAmt:
|
|
1108
|
+
mintedAmt: totalCdpDebt - redemptionIAssetAmt,
|
|
867
1109
|
cdpFees: {
|
|
868
1110
|
ActiveCDPInterestTracking: {
|
|
869
1111
|
lastSettled: currentTime,
|
|
@@ -879,33 +1121,27 @@ export async function redeemCdp(
|
|
|
879
1121
|
},
|
|
880
1122
|
addAssets(
|
|
881
1123
|
cdpUtxo.assets,
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
1124
|
+
mkAssetsOf(
|
|
1125
|
+
cdpDatum.collateralAsset,
|
|
1126
|
+
-redemptionCollateralAmt + reimburstmentFee,
|
|
1127
|
+
),
|
|
885
1128
|
),
|
|
886
1129
|
);
|
|
887
1130
|
|
|
888
|
-
await collectorFeeTx(
|
|
889
|
-
processingFee + partialRedemptionFee + interestCollectorAdaAmt,
|
|
890
|
-
lucid,
|
|
891
|
-
sysParams,
|
|
892
|
-
tx,
|
|
893
|
-
collector,
|
|
894
|
-
);
|
|
895
|
-
|
|
896
|
-
await treasuryFeeTx(interestTreasuryAdaAmt, lucid, sysParams, tx, treasury);
|
|
897
|
-
|
|
898
1131
|
return tx;
|
|
899
1132
|
}
|
|
900
1133
|
|
|
901
1134
|
export async function freezeCdp(
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
1135
|
+
cdpOref: OutRef,
|
|
1136
|
+
iassetOref: OutRef,
|
|
1137
|
+
collateralAssetOref: OutRef,
|
|
1138
|
+
priceOracleOref: OutRef | undefined,
|
|
1139
|
+
interestOracleOref: OutRef,
|
|
906
1140
|
sysParams: SystemParams,
|
|
907
1141
|
lucid: LucidEvolution,
|
|
908
1142
|
currentSlot: number,
|
|
1143
|
+
pythMessage: string | undefined = undefined,
|
|
1144
|
+
pythStateOref: OutRef | undefined = undefined,
|
|
909
1145
|
): Promise<TxBuilder> {
|
|
910
1146
|
const network = lucid.config().network!;
|
|
911
1147
|
const currentTime = BigInt(slotToUnixTime(network, currentSlot));
|
|
@@ -916,137 +1152,145 @@ export async function freezeCdp(
|
|
|
916
1152
|
]),
|
|
917
1153
|
(_) => new Error('Expected a single cdp Ref Script UTXO'),
|
|
918
1154
|
);
|
|
919
|
-
const cdpUtxo =
|
|
1155
|
+
const cdpUtxo = matchSingle(
|
|
1156
|
+
await lucid.utxosByOutRef([cdpOref]),
|
|
1157
|
+
(_) => new Error('Expected a single cdp UTXO'),
|
|
1158
|
+
);
|
|
920
1159
|
const cdpDatum = parseCdpDatumOrThrow(getInlineDatumOrThrow(cdpUtxo));
|
|
921
1160
|
|
|
922
|
-
const iassetUtxo =
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
'Expected a single iasset UTXO',
|
|
1161
|
+
const iassetUtxo = matchSingle(
|
|
1162
|
+
await lucid.utxosByOutRef([iassetOref]),
|
|
1163
|
+
(_) => new Error('Expected a single iasset UTXO'),
|
|
926
1164
|
);
|
|
927
1165
|
const iassetDatum = parseIAssetDatumOrThrow(
|
|
928
1166
|
getInlineDatumOrThrow(iassetUtxo),
|
|
929
1167
|
);
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
lucid,
|
|
934
|
-
'Expected a single price oracle UTXO',
|
|
1168
|
+
const collateralAssetUtxo = matchSingle(
|
|
1169
|
+
await lucid.utxosByOutRef([collateralAssetOref]),
|
|
1170
|
+
(_) => new Error('Expected a single collateral asset UTXO'),
|
|
935
1171
|
);
|
|
936
|
-
const
|
|
937
|
-
getInlineDatumOrThrow(
|
|
1172
|
+
const collateralAssetDatum = parseCollateralAssetDatumOrThrow(
|
|
1173
|
+
getInlineDatumOrThrow(collateralAssetUtxo),
|
|
938
1174
|
);
|
|
939
1175
|
|
|
940
|
-
const
|
|
941
|
-
|
|
1176
|
+
const [adjustedPrice, _] = await retrieveAdjustedPrice(
|
|
1177
|
+
iassetDatum.assetName,
|
|
1178
|
+
collateralAssetDatum.collateralAsset,
|
|
1179
|
+
collateralAssetDatum.priceInfo,
|
|
1180
|
+
collateralAssetDatum.extraDecimals,
|
|
1181
|
+
priceOracleOref,
|
|
1182
|
+
pythMessage,
|
|
1183
|
+
sysParams.pythConfig,
|
|
942
1184
|
lucid,
|
|
943
|
-
|
|
1185
|
+
);
|
|
1186
|
+
|
|
1187
|
+
const interestOracleUtxo = matchSingle(
|
|
1188
|
+
await lucid.utxosByOutRef([interestOracleOref]),
|
|
1189
|
+
(_) => new Error('Expected a single interest oracle UTXO'),
|
|
944
1190
|
);
|
|
945
1191
|
const interestOracleDatum = parseInterestOracleDatum(
|
|
946
1192
|
getInlineDatumOrThrow(interestOracleUtxo),
|
|
947
1193
|
);
|
|
948
1194
|
|
|
949
|
-
const
|
|
1195
|
+
const interestAmt = match(cdpDatum.cdpFees)
|
|
950
1196
|
.with({ FrozenCDPAccumulatedFees: P.any }, () => {
|
|
951
1197
|
throw new Error('CDP fees wrong');
|
|
952
1198
|
})
|
|
953
1199
|
.with({ ActiveCDPInterestTracking: P.select() }, (interest) => {
|
|
954
|
-
|
|
1200
|
+
return calculateAccruedInterest(
|
|
955
1201
|
currentTime,
|
|
956
1202
|
interest.unitaryInterestSnapshot,
|
|
957
1203
|
cdpDatum.mintedAmt,
|
|
958
1204
|
interest.lastSettled,
|
|
959
1205
|
interestOracleDatum,
|
|
960
1206
|
);
|
|
961
|
-
|
|
962
|
-
const maxInterestLovelaces = computeInterestLovelacesFor100PercentCR(
|
|
963
|
-
lovelacesAmt(cdpUtxo.assets),
|
|
964
|
-
cdpDatum.mintedAmt,
|
|
965
|
-
priceOracleDatum.price,
|
|
966
|
-
);
|
|
967
|
-
|
|
968
|
-
return bigintMin(
|
|
969
|
-
maxInterestLovelaces,
|
|
970
|
-
ocdMul(
|
|
971
|
-
{ getOnChainInt: interestPaymentIAssetAmt },
|
|
972
|
-
priceOracleDatum.price,
|
|
973
|
-
).getOnChainInt,
|
|
974
|
-
);
|
|
975
1207
|
})
|
|
976
1208
|
.exhaustive();
|
|
977
1209
|
|
|
978
|
-
const
|
|
979
|
-
|
|
980
|
-
|
|
1210
|
+
const inputCollateral = assetClassValueOf(
|
|
1211
|
+
cdpUtxo.assets,
|
|
1212
|
+
cdpDatum.collateralAsset,
|
|
981
1213
|
);
|
|
982
1214
|
|
|
983
|
-
const
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
{ getOnChainInt: cdpDatum.mintedAmt },
|
|
990
|
-
priceOracleDatum.price,
|
|
991
|
-
).getOnChainInt;
|
|
1215
|
+
const cdpDebtCollateralValue = rationalFloor(
|
|
1216
|
+
rationalMul(
|
|
1217
|
+
rationalFromInt(cdpDatum.mintedAmt + interestAmt),
|
|
1218
|
+
adjustedPrice,
|
|
1219
|
+
),
|
|
1220
|
+
);
|
|
992
1221
|
|
|
993
1222
|
const liquidationProcessingFee = bigintMin(
|
|
994
|
-
|
|
995
|
-
iassetDatum.
|
|
996
|
-
|
|
997
|
-
),
|
|
998
|
-
calculateFeeFromPercentage(
|
|
999
|
-
iassetDatum.liquidationProcessingFeePercentage,
|
|
1000
|
-
cdpDebtAdaValue,
|
|
1223
|
+
calculateFeeFromRatio(
|
|
1224
|
+
iassetDatum.liquidationProcessingFeeRatio,
|
|
1225
|
+
inputCollateral,
|
|
1001
1226
|
),
|
|
1227
|
+
bigintMax(0n, inputCollateral - cdpDebtCollateralValue),
|
|
1002
1228
|
);
|
|
1003
1229
|
|
|
1004
|
-
|
|
1230
|
+
let referenceInputs = [iassetUtxo, collateralAssetUtxo, interestOracleUtxo];
|
|
1231
|
+
const referenceScripts = [cdpRefScriptUtxo];
|
|
1232
|
+
|
|
1233
|
+
const tx = lucid.newTx();
|
|
1234
|
+
|
|
1235
|
+
const { interval, referenceInputs: oracleRefInputs } = await attachOracle(
|
|
1236
|
+
iassetDatum.assetName,
|
|
1237
|
+
collateralAssetDatum.collateralAsset,
|
|
1238
|
+
collateralAssetDatum.priceInfo,
|
|
1239
|
+
priceOracleOref,
|
|
1240
|
+
pythStateOref,
|
|
1241
|
+
pythMessage,
|
|
1242
|
+
sysParams.pythConfig,
|
|
1243
|
+
sysParams.cdpParams.biasTime,
|
|
1005
1244
|
currentSlot,
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
network,
|
|
1009
|
-
);
|
|
1010
|
-
|
|
1011
|
-
return (
|
|
1012
|
-
lucid
|
|
1013
|
-
.newTx()
|
|
1014
|
-
// Ref Script
|
|
1015
|
-
.readFrom([cdpRefScriptUtxo])
|
|
1016
|
-
// Ref inputs
|
|
1017
|
-
.readFrom([iassetUtxo, priceOracleUtxo, interestOracleUtxo])
|
|
1018
|
-
.validFrom(txValidity.validFrom)
|
|
1019
|
-
.validTo(txValidity.validTo)
|
|
1020
|
-
.collectFrom(
|
|
1021
|
-
[cdpUtxo],
|
|
1022
|
-
serialiseCdpRedeemer({ FreezeCdp: { currentTime: currentTime } }),
|
|
1023
|
-
)
|
|
1024
|
-
.pay.ToContract(
|
|
1025
|
-
createScriptAddress(network, sysParams.validatorHashes.cdpHash),
|
|
1026
|
-
{
|
|
1027
|
-
kind: 'inline',
|
|
1028
|
-
value: serialiseCdpDatum({
|
|
1029
|
-
...cdpDatum,
|
|
1030
|
-
cdpOwner: null,
|
|
1031
|
-
cdpFees: {
|
|
1032
|
-
FrozenCDPAccumulatedFees: {
|
|
1033
|
-
lovelacesIndyStakers:
|
|
1034
|
-
liquidationProcessingFee + interestCollectorAdaAmt,
|
|
1035
|
-
lovelacesTreasury: interestTreasuryAdaAmt,
|
|
1036
|
-
},
|
|
1037
|
-
},
|
|
1038
|
-
}),
|
|
1039
|
-
},
|
|
1040
|
-
cdpUtxo.assets,
|
|
1041
|
-
)
|
|
1245
|
+
lucid,
|
|
1246
|
+
tx,
|
|
1042
1247
|
);
|
|
1248
|
+
|
|
1249
|
+
referenceInputs = [...oracleRefInputs, ...referenceInputs];
|
|
1250
|
+
|
|
1251
|
+
const refInputsIndices = getInputIndices(referenceInputs, [
|
|
1252
|
+
...referenceInputs,
|
|
1253
|
+
...referenceScripts,
|
|
1254
|
+
]);
|
|
1255
|
+
|
|
1256
|
+
return tx
|
|
1257
|
+
.readFrom(referenceScripts)
|
|
1258
|
+
.readFrom(referenceInputs)
|
|
1259
|
+
.validFrom(interval.validFrom)
|
|
1260
|
+
.validTo(interval.validTo)
|
|
1261
|
+
.collectFrom(
|
|
1262
|
+
[cdpUtxo],
|
|
1263
|
+
serialiseCdpRedeemer({
|
|
1264
|
+
FreezeCdp: {
|
|
1265
|
+
currentTime: currentTime,
|
|
1266
|
+
priceOracleIdx: { OracleRefInputIdx: refInputsIndices[0] },
|
|
1267
|
+
},
|
|
1268
|
+
}),
|
|
1269
|
+
)
|
|
1270
|
+
.pay.ToContract(
|
|
1271
|
+
createScriptAddress(network, sysParams.validatorHashes.cdpHash),
|
|
1272
|
+
{
|
|
1273
|
+
kind: 'inline',
|
|
1274
|
+
value: serialiseCdpDatum({
|
|
1275
|
+
...cdpDatum,
|
|
1276
|
+
cdpOwner: null,
|
|
1277
|
+
cdpFees: {
|
|
1278
|
+
FrozenCDPAccumulatedFees: {
|
|
1279
|
+
iassetInterest: interestAmt,
|
|
1280
|
+
collateralTreasury: liquidationProcessingFee,
|
|
1281
|
+
},
|
|
1282
|
+
},
|
|
1283
|
+
}),
|
|
1284
|
+
},
|
|
1285
|
+
cdpUtxo.assets,
|
|
1286
|
+
);
|
|
1043
1287
|
}
|
|
1044
1288
|
|
|
1045
1289
|
export async function liquidateCdp(
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1290
|
+
cdpOref: OutRef,
|
|
1291
|
+
stabilityPoolOref: OutRef,
|
|
1292
|
+
interestCollectorOref: OutRef,
|
|
1293
|
+
treasuryOref: OutRef,
|
|
1050
1294
|
sysParams: SystemParams,
|
|
1051
1295
|
lucid: LucidEvolution,
|
|
1052
1296
|
): Promise<TxBuilder> {
|
|
@@ -1081,21 +1325,23 @@ export async function liquidateCdp(
|
|
|
1081
1325
|
(_) => new Error('Expected a single cdp auth token policy Ref Script UTXO'),
|
|
1082
1326
|
);
|
|
1083
1327
|
|
|
1084
|
-
const cdpUtxo =
|
|
1328
|
+
const cdpUtxo = matchSingle(
|
|
1329
|
+
await lucid.utxosByOutRef([cdpOref]),
|
|
1330
|
+
(_) => new Error('Expected a single cdp UTXO'),
|
|
1331
|
+
);
|
|
1085
1332
|
const cdpDatum = parseCdpDatumOrThrow(getInlineDatumOrThrow(cdpUtxo));
|
|
1086
1333
|
|
|
1087
|
-
const spUtxo =
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
'Expected a single stability pool UTXO',
|
|
1334
|
+
const spUtxo = matchSingle(
|
|
1335
|
+
await lucid.utxosByOutRef([stabilityPoolOref]),
|
|
1336
|
+
(_) => new Error('Expected a single stability pool UTXO'),
|
|
1091
1337
|
);
|
|
1092
|
-
const spDatum =
|
|
1338
|
+
const spDatum = parseStabilityPoolDatumOrThrow(getInlineDatumOrThrow(spUtxo));
|
|
1093
1339
|
|
|
1094
|
-
const [
|
|
1340
|
+
const [frozenInterest, collateralForTreasury] = match(cdpDatum.cdpFees)
|
|
1095
1341
|
.returnType<[bigint, bigint]>()
|
|
1096
1342
|
.with({ FrozenCDPAccumulatedFees: P.select() }, (fees) => [
|
|
1097
|
-
fees.
|
|
1098
|
-
fees.
|
|
1343
|
+
fees.iassetInterest,
|
|
1344
|
+
fees.collateralTreasury,
|
|
1099
1345
|
])
|
|
1100
1346
|
.with({ ActiveCDPInterestTracking: P.any }, () => {
|
|
1101
1347
|
throw new Error('CDP fees wrong');
|
|
@@ -1104,21 +1350,36 @@ export async function liquidateCdp(
|
|
|
1104
1350
|
|
|
1105
1351
|
const cdpNftAc = fromSystemParamsAsset(sysParams.cdpParams.cdpAuthToken);
|
|
1106
1352
|
const iassetsAc = {
|
|
1107
|
-
currencySymbol:
|
|
1353
|
+
currencySymbol: fromHex(
|
|
1354
|
+
sysParams.cdpParams.cdpAssetSymbol.unCurrencySymbol,
|
|
1355
|
+
),
|
|
1108
1356
|
tokenName: cdpDatum.iasset,
|
|
1109
1357
|
};
|
|
1110
1358
|
|
|
1111
1359
|
const spIassetAmt = assetClassValueOf(spUtxo.assets, iassetsAc);
|
|
1112
1360
|
|
|
1113
|
-
const
|
|
1361
|
+
const totalCdpDebt = cdpDatum.mintedAmt + frozenInterest;
|
|
1362
|
+
|
|
1363
|
+
// Take from the SP enough as much iAsset as possible to pay out the debt.
|
|
1364
|
+
const iassetUsedAmt = bigintMin(totalCdpDebt, spIassetAmt);
|
|
1114
1365
|
|
|
1115
|
-
const collateralAvailable =
|
|
1116
|
-
|
|
1117
|
-
|
|
1366
|
+
const collateralAvailable = assetClassValueOf(
|
|
1367
|
+
cdpUtxo.assets,
|
|
1368
|
+
cdpDatum.collateralAsset,
|
|
1369
|
+
);
|
|
1370
|
+
const collateralAvailMinusFees = collateralAvailable - collateralForTreasury;
|
|
1118
1371
|
const collateralAbsorbed =
|
|
1119
|
-
(collateralAvailMinusFees *
|
|
1372
|
+
(collateralAvailMinusFees * iassetUsedAmt) / totalCdpDebt;
|
|
1373
|
+
|
|
1374
|
+
const isPartial = spIassetAmt < totalCdpDebt;
|
|
1375
|
+
|
|
1376
|
+
// Interest partially paid if the liquidity in the SP is not enough to cover it.
|
|
1377
|
+
const remainingInterest = bigintMax(frozenInterest - spIassetAmt, 0n);
|
|
1378
|
+
|
|
1379
|
+
const payableInterest = frozenInterest - remainingInterest;
|
|
1120
1380
|
|
|
1121
|
-
|
|
1381
|
+
// All the iAsset taken from the SP and not used to pay out the interest must be burnt.
|
|
1382
|
+
const iassetBurnAmt = iassetUsedAmt - payableInterest;
|
|
1122
1383
|
|
|
1123
1384
|
const tx = lucid
|
|
1124
1385
|
.newTx()
|
|
@@ -1138,18 +1399,32 @@ export async function liquidateCdp(
|
|
|
1138
1399
|
value: serialiseStabilityPoolDatum({
|
|
1139
1400
|
StabilityPool: liquidationHelper(
|
|
1140
1401
|
spDatum,
|
|
1141
|
-
|
|
1402
|
+
cdpDatum.collateralAsset,
|
|
1403
|
+
iassetUsedAmt,
|
|
1142
1404
|
collateralAbsorbed,
|
|
1143
|
-
)
|
|
1405
|
+
),
|
|
1144
1406
|
}),
|
|
1145
1407
|
},
|
|
1146
1408
|
addAssets(
|
|
1147
1409
|
spUtxo.assets,
|
|
1148
|
-
|
|
1149
|
-
mkAssetsOf(iassetsAc, -
|
|
1410
|
+
mkAssetsOf(cdpDatum.collateralAsset, collateralAbsorbed),
|
|
1411
|
+
mkAssetsOf(iassetsAc, -iassetUsedAmt),
|
|
1150
1412
|
),
|
|
1151
1413
|
);
|
|
1152
1414
|
|
|
1415
|
+
if (collateralForTreasury > 0n) {
|
|
1416
|
+
await treasuryFeeTx(
|
|
1417
|
+
cdpDatum.collateralAsset,
|
|
1418
|
+
collateralForTreasury,
|
|
1419
|
+
0n,
|
|
1420
|
+
lucid,
|
|
1421
|
+
sysParams,
|
|
1422
|
+
tx,
|
|
1423
|
+
cdpOref,
|
|
1424
|
+
treasuryOref,
|
|
1425
|
+
);
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1153
1428
|
if (isPartial) {
|
|
1154
1429
|
tx.pay.ToContract(
|
|
1155
1430
|
cdpUtxo.address,
|
|
@@ -1157,18 +1432,23 @@ export async function liquidateCdp(
|
|
|
1157
1432
|
kind: 'inline',
|
|
1158
1433
|
value: serialiseCdpDatum({
|
|
1159
1434
|
...cdpDatum,
|
|
1160
|
-
mintedAmt: cdpDatum.mintedAmt -
|
|
1435
|
+
mintedAmt: cdpDatum.mintedAmt - iassetBurnAmt,
|
|
1161
1436
|
cdpFees: {
|
|
1162
1437
|
FrozenCDPAccumulatedFees: {
|
|
1163
|
-
|
|
1164
|
-
|
|
1438
|
+
iassetInterest: remainingInterest,
|
|
1439
|
+
collateralTreasury: 0n,
|
|
1165
1440
|
},
|
|
1166
1441
|
},
|
|
1167
1442
|
}),
|
|
1168
1443
|
},
|
|
1169
1444
|
addAssets(
|
|
1170
|
-
|
|
1171
|
-
|
|
1445
|
+
cdpUtxo.assets,
|
|
1446
|
+
negateAssets(
|
|
1447
|
+
mkAssetsOf(
|
|
1448
|
+
cdpDatum.collateralAsset,
|
|
1449
|
+
collateralForTreasury + collateralAbsorbed,
|
|
1450
|
+
),
|
|
1451
|
+
),
|
|
1172
1452
|
),
|
|
1173
1453
|
);
|
|
1174
1454
|
} else {
|
|
@@ -1178,9 +1458,15 @@ export async function liquidateCdp(
|
|
|
1178
1458
|
);
|
|
1179
1459
|
}
|
|
1180
1460
|
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1461
|
+
if (payableInterest > 0) {
|
|
1462
|
+
await collectInterestTx(
|
|
1463
|
+
mkAssetsOf(iassetsAc, payableInterest),
|
|
1464
|
+
lucid,
|
|
1465
|
+
sysParams,
|
|
1466
|
+
tx,
|
|
1467
|
+
interestCollectorOref,
|
|
1468
|
+
);
|
|
1469
|
+
}
|
|
1184
1470
|
|
|
1185
1471
|
return tx;
|
|
1186
1472
|
}
|
|
@@ -1217,22 +1503,21 @@ export async function mergeCdps(
|
|
|
1217
1503
|
);
|
|
1218
1504
|
|
|
1219
1505
|
type AggregatedFees = {
|
|
1220
|
-
|
|
1221
|
-
|
|
1506
|
+
aggregatedCollateralTreasury: bigint;
|
|
1507
|
+
aggregatedInterest: bigint;
|
|
1222
1508
|
};
|
|
1223
1509
|
|
|
1224
|
-
const {
|
|
1510
|
+
const { aggregatedInterest, aggregatedCollateralTreasury } = F.pipe(
|
|
1225
1511
|
cdpDatums,
|
|
1226
1512
|
A.reduce<CDPContent, AggregatedFees>(
|
|
1227
|
-
{
|
|
1513
|
+
{ aggregatedCollateralTreasury: 0n, aggregatedInterest: 0n },
|
|
1228
1514
|
(acc, cdpDat) =>
|
|
1229
1515
|
match(cdpDat.cdpFees)
|
|
1230
1516
|
.returnType<AggregatedFees>()
|
|
1231
1517
|
.with({ FrozenCDPAccumulatedFees: P.select() }, (fees) => ({
|
|
1232
|
-
|
|
1233
|
-
acc.
|
|
1234
|
-
|
|
1235
|
-
acc.aggregatedFeeTreasury + fees.lovelacesTreasury,
|
|
1518
|
+
aggregatedCollateralTreasury:
|
|
1519
|
+
acc.aggregatedCollateralTreasury + fees.collateralTreasury,
|
|
1520
|
+
aggregatedInterest: acc.aggregatedInterest + fees.iassetInterest,
|
|
1236
1521
|
}))
|
|
1237
1522
|
.otherwise(() => acc),
|
|
1238
1523
|
),
|
|
@@ -1260,7 +1545,7 @@ export async function mergeCdps(
|
|
|
1260
1545
|
MergeAuxiliary: {
|
|
1261
1546
|
mainMergeUtxo: {
|
|
1262
1547
|
outputIndex: BigInt(mainMergeUtxo.outputIndex),
|
|
1263
|
-
txHash:
|
|
1548
|
+
txHash: fromHex(mainMergeUtxo.txHash),
|
|
1264
1549
|
},
|
|
1265
1550
|
},
|
|
1266
1551
|
}),
|
|
@@ -1272,11 +1557,12 @@ export async function mergeCdps(
|
|
|
1272
1557
|
value: serialiseCdpDatum({
|
|
1273
1558
|
cdpOwner: null,
|
|
1274
1559
|
iasset: mainCdpDatum.iasset,
|
|
1560
|
+
collateralAsset: mainCdpDatum.collateralAsset,
|
|
1275
1561
|
mintedAmt: aggregatedMintedAmt,
|
|
1276
1562
|
cdpFees: {
|
|
1277
1563
|
FrozenCDPAccumulatedFees: {
|
|
1278
|
-
|
|
1279
|
-
|
|
1564
|
+
collateralTreasury: aggregatedCollateralTreasury,
|
|
1565
|
+
iassetInterest: aggregatedInterest,
|
|
1280
1566
|
},
|
|
1281
1567
|
},
|
|
1282
1568
|
}),
|