@indigo-labs/indigo-sdk 0.2.1 → 0.2.4
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/dist/index.d.mts +245 -17
- package/dist/index.d.ts +245 -17
- package/dist/index.js +1144 -479
- package/dist/index.mjs +970 -319
- package/package.json +1 -1
- package/src/contracts/collector/transactions.ts +3 -3
- package/src/contracts/collector/types.ts +16 -0
- package/src/contracts/leverage/helpers.ts +424 -0
- package/src/contracts/leverage/transactions.ts +274 -0
- package/src/contracts/lrp/helpers.ts +290 -0
- package/src/contracts/lrp/transactions.ts +42 -104
- package/src/contracts/lrp/types.ts +19 -3
- package/src/contracts/stability-pool/transactions.ts +0 -4
- package/src/contracts/staking/helpers.ts +11 -0
- package/src/contracts/staking/transactions.ts +94 -4
- package/src/index.ts +7 -2
- package/src/types/on-chain-decimal.ts +4 -0
- package/src/utils/array-utils.ts +39 -0
- package/src/utils/bigint-utils.ts +16 -0
- package/tests/array-utils.test.ts +92 -0
- package/tests/cdp.test.ts +83 -120
- package/tests/endpoints/initialize.ts +1 -1
- package/tests/lrp-leverage.test.ts +1495 -0
- package/tests/lrp.test.ts +436 -658
- package/tests/mock/assets-mock.ts +2 -2
- package/tests/queries/cdp-queries.ts +76 -0
- package/tests/queries/lrp-queries.ts +41 -4
- package/tests/staking.test.ts +71 -16
- package/tests/indigo-test-helpers.ts +0 -61
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
LucidEvolution,
|
|
3
|
-
Network,
|
|
4
|
-
ScriptHash,
|
|
5
3
|
TxBuilder,
|
|
6
4
|
Credential,
|
|
7
5
|
OutRef,
|
|
8
|
-
UTxO,
|
|
9
6
|
addAssets,
|
|
10
7
|
unixTimeToSlot,
|
|
11
8
|
slotToUnixTime,
|
|
@@ -15,39 +12,39 @@ import {
|
|
|
15
12
|
createScriptAddress,
|
|
16
13
|
getInlineDatumOrThrow,
|
|
17
14
|
} from '../../utils/lucid-utils';
|
|
18
|
-
import { match, P } from 'ts-pattern';
|
|
19
15
|
import { unzip, zip } from 'fp-ts/lib/Array';
|
|
20
|
-
import { reduceWithIndex } from 'fp-ts/lib/Array';
|
|
21
16
|
import {
|
|
22
17
|
LRPDatum,
|
|
23
|
-
|
|
24
|
-
parseLrpDatum,
|
|
18
|
+
parseLrpDatumOrThrow,
|
|
25
19
|
serialiseLrpDatum,
|
|
26
20
|
serialiseLrpRedeemer,
|
|
27
21
|
} from './types';
|
|
28
22
|
import { parsePriceOracleDatum } from '../price-oracle/types';
|
|
29
|
-
import {
|
|
23
|
+
import { OnChainDecimal } from '../../types/on-chain-decimal';
|
|
30
24
|
import { parseIAssetDatumOrThrow } from '../cdp/types';
|
|
31
25
|
import {
|
|
32
26
|
assetClassValueOf,
|
|
33
27
|
mkAssetsOf,
|
|
34
28
|
mkLovelacesOf,
|
|
35
29
|
} from '../../utils/value-helpers';
|
|
36
|
-
import { calculateFeeFromPercentage } from '../../utils/indigo-helpers';
|
|
37
30
|
import { matchSingle } from '../../utils/utils';
|
|
38
31
|
import { AssetClass } from '../../types/generic';
|
|
39
|
-
|
|
40
|
-
|
|
32
|
+
import {
|
|
33
|
+
fromSystemParamsScriptRef,
|
|
34
|
+
SystemParams,
|
|
35
|
+
} from '../../types/system-params';
|
|
36
|
+
import { buildRedemptionsTx, MIN_LRP_COLLATERAL_AMT } from './helpers';
|
|
41
37
|
|
|
42
38
|
export async function openLrp(
|
|
43
39
|
assetTokenName: string,
|
|
44
40
|
lovelacesAmt: bigint,
|
|
45
41
|
maxPrice: OnChainDecimal,
|
|
46
42
|
lucid: LucidEvolution,
|
|
47
|
-
|
|
48
|
-
network: Network,
|
|
43
|
+
sysParams: SystemParams,
|
|
49
44
|
lrpStakeCredential?: Credential,
|
|
50
45
|
): Promise<TxBuilder> {
|
|
46
|
+
const network = lucid.config().network!;
|
|
47
|
+
|
|
51
48
|
const [ownPkh, _] = await addrDetails(lucid);
|
|
52
49
|
|
|
53
50
|
const newDatum: LRPDatum = {
|
|
@@ -58,22 +55,28 @@ export async function openLrp(
|
|
|
58
55
|
};
|
|
59
56
|
|
|
60
57
|
return lucid.newTx().pay.ToContract(
|
|
61
|
-
createScriptAddress(
|
|
58
|
+
createScriptAddress(
|
|
59
|
+
network,
|
|
60
|
+
sysParams.validatorHashes.lrpHash,
|
|
61
|
+
lrpStakeCredential,
|
|
62
|
+
),
|
|
62
63
|
{
|
|
63
64
|
kind: 'inline',
|
|
64
65
|
value: serialiseLrpDatum(newDatum),
|
|
65
66
|
},
|
|
66
|
-
{ lovelace: lovelacesAmt +
|
|
67
|
+
{ lovelace: lovelacesAmt + MIN_LRP_COLLATERAL_AMT },
|
|
67
68
|
);
|
|
68
69
|
}
|
|
69
70
|
|
|
70
71
|
export async function cancelLrp(
|
|
71
72
|
lrpOutRef: OutRef,
|
|
72
|
-
|
|
73
|
+
sysParams: SystemParams,
|
|
73
74
|
lucid: LucidEvolution,
|
|
74
75
|
): Promise<TxBuilder> {
|
|
75
76
|
const lrpScriptRefUtxo = matchSingle(
|
|
76
|
-
await lucid.utxosByOutRef([
|
|
77
|
+
await lucid.utxosByOutRef([
|
|
78
|
+
fromSystemParamsScriptRef(sysParams.scriptReferences.lrpValidatorRef),
|
|
79
|
+
]),
|
|
77
80
|
(_) => new Error('Expected a single LRP Ref Script UTXO'),
|
|
78
81
|
);
|
|
79
82
|
|
|
@@ -82,7 +85,7 @@ export async function cancelLrp(
|
|
|
82
85
|
(_) => new Error('Expected a single LRP UTXO.'),
|
|
83
86
|
);
|
|
84
87
|
|
|
85
|
-
const lrpDatum =
|
|
88
|
+
const lrpDatum = parseLrpDatumOrThrow(getInlineDatumOrThrow(lrpUtxo));
|
|
86
89
|
|
|
87
90
|
return lucid
|
|
88
91
|
.newTx()
|
|
@@ -94,15 +97,17 @@ export async function cancelLrp(
|
|
|
94
97
|
export async function redeemLrp(
|
|
95
98
|
/** The tuple represents the LRP outref and the amount of iAssets to redeem against it. */
|
|
96
99
|
redemptionLrpsData: [OutRef, bigint][],
|
|
97
|
-
lrpRefScriptOutRef: OutRef,
|
|
98
100
|
priceOracleOutRef: OutRef,
|
|
99
101
|
iassetOutRef: OutRef,
|
|
100
102
|
lucid: LucidEvolution,
|
|
101
|
-
|
|
102
|
-
network: Network,
|
|
103
|
+
sysParams: SystemParams,
|
|
103
104
|
): Promise<TxBuilder> {
|
|
105
|
+
const network = lucid.config().network!;
|
|
106
|
+
|
|
104
107
|
const lrpScriptRefUtxo = matchSingle(
|
|
105
|
-
await lucid.utxosByOutRef([
|
|
108
|
+
await lucid.utxosByOutRef([
|
|
109
|
+
fromSystemParamsScriptRef(sysParams.scriptReferences.lrpValidatorRef),
|
|
110
|
+
]),
|
|
106
111
|
(_) => new Error('Expected a single LRP Ref Script UTXO'),
|
|
107
112
|
);
|
|
108
113
|
|
|
@@ -131,81 +136,14 @@ export async function redeemLrp(
|
|
|
131
136
|
.utxosByOutRef(lrpsToRedeemOutRefs)
|
|
132
137
|
.then((val) => zip(val, lrpRedemptionIAssetAmt));
|
|
133
138
|
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
rest,
|
|
140
|
-
],
|
|
141
|
-
)
|
|
142
|
-
.otherwise(() => {
|
|
143
|
-
throw new Error('Expects at least 1 UTXO to redeem.');
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
const mainLrpDatum = parseLrpDatum(getInlineDatumOrThrow(mainLrpUtxo));
|
|
147
|
-
|
|
148
|
-
const tx = reduceWithIndex<[UTxO, bigint], TxBuilder>(
|
|
139
|
+
const tx = buildRedemptionsTx(
|
|
140
|
+
redemptionLrps,
|
|
141
|
+
priceOracleDatum.price,
|
|
142
|
+
iassetDatum.redemptionReimbursementPercentage,
|
|
143
|
+
sysParams,
|
|
149
144
|
lucid.newTx(),
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
{
|
|
153
|
-
getOnChainInt: redeemIAssetAmt,
|
|
154
|
-
},
|
|
155
|
-
priceOracleDatum.price,
|
|
156
|
-
).getOnChainInt;
|
|
157
|
-
const reimburstmentLovelaces = calculateFeeFromPercentage(
|
|
158
|
-
iassetDatum.redemptionReimbursementPercentage,
|
|
159
|
-
lovelacesForRedemption,
|
|
160
|
-
);
|
|
161
|
-
|
|
162
|
-
const lrpDatum = parseLrpDatum(getInlineDatumOrThrow(lrpUtxo));
|
|
163
|
-
|
|
164
|
-
return acc
|
|
165
|
-
.collectFrom(
|
|
166
|
-
[lrpUtxo],
|
|
167
|
-
serialiseLrpRedeemer(
|
|
168
|
-
idx === 0
|
|
169
|
-
? { Redeem: { continuingOutputIdx: 0n } }
|
|
170
|
-
: {
|
|
171
|
-
RedeemAuxiliary: {
|
|
172
|
-
continuingOutputIdx: BigInt(idx),
|
|
173
|
-
mainRedeemOutRef: {
|
|
174
|
-
txHash: { hash: mainLrpUtxo.txHash },
|
|
175
|
-
outputIndex: BigInt(mainLrpUtxo.outputIndex),
|
|
176
|
-
},
|
|
177
|
-
asset: mainLrpDatum.iasset,
|
|
178
|
-
assetPrice: priceOracleDatum.price,
|
|
179
|
-
redemptionReimbursementPercentage:
|
|
180
|
-
iassetDatum.redemptionReimbursementPercentage,
|
|
181
|
-
},
|
|
182
|
-
},
|
|
183
|
-
),
|
|
184
|
-
)
|
|
185
|
-
.pay.ToContract(
|
|
186
|
-
lrpUtxo.address,
|
|
187
|
-
{
|
|
188
|
-
kind: 'inline',
|
|
189
|
-
value: serialiseLrpDatum({
|
|
190
|
-
...lrpDatum,
|
|
191
|
-
lovelacesToSpend:
|
|
192
|
-
lrpDatum.lovelacesToSpend - lovelacesForRedemption,
|
|
193
|
-
}),
|
|
194
|
-
},
|
|
195
|
-
addAssets(
|
|
196
|
-
lrpUtxo.assets,
|
|
197
|
-
mkLovelacesOf(-lovelacesForRedemption + reimburstmentLovelaces),
|
|
198
|
-
mkAssetsOf(
|
|
199
|
-
{
|
|
200
|
-
currencySymbol: lrpParams.iassetPolicyId,
|
|
201
|
-
tokenName: mainLrpDatum.iasset,
|
|
202
|
-
},
|
|
203
|
-
redeemIAssetAmt,
|
|
204
|
-
),
|
|
205
|
-
),
|
|
206
|
-
);
|
|
207
|
-
},
|
|
208
|
-
)(redemptionLrps);
|
|
145
|
+
0n,
|
|
146
|
+
);
|
|
209
147
|
|
|
210
148
|
return (
|
|
211
149
|
lucid
|
|
@@ -235,11 +173,12 @@ export async function adjustLrp(
|
|
|
235
173
|
* and a negative amount takes lovelaces from the LRP.
|
|
236
174
|
*/
|
|
237
175
|
lovelacesAdjustAmt: bigint,
|
|
238
|
-
|
|
239
|
-
lrpParams: LRPParams,
|
|
176
|
+
sysParams: SystemParams,
|
|
240
177
|
): Promise<TxBuilder> {
|
|
241
178
|
const lrpScriptRefUtxo = matchSingle(
|
|
242
|
-
await lucid.utxosByOutRef([
|
|
179
|
+
await lucid.utxosByOutRef([
|
|
180
|
+
fromSystemParamsScriptRef(sysParams.scriptReferences.lrpValidatorRef),
|
|
181
|
+
]),
|
|
243
182
|
(_) => new Error('Expected a single LRP Ref Script UTXO'),
|
|
244
183
|
);
|
|
245
184
|
|
|
@@ -248,10 +187,10 @@ export async function adjustLrp(
|
|
|
248
187
|
(_) => new Error('Expected a single LRP UTXO.'),
|
|
249
188
|
);
|
|
250
189
|
|
|
251
|
-
const lrpDatum =
|
|
190
|
+
const lrpDatum = parseLrpDatumOrThrow(getInlineDatumOrThrow(lrpUtxo));
|
|
252
191
|
|
|
253
192
|
const rewardAssetClass: AssetClass = {
|
|
254
|
-
currencySymbol: lrpParams.iassetPolicyId,
|
|
193
|
+
currencySymbol: sysParams.lrpParams.iassetPolicyId.unCurrencySymbol,
|
|
255
194
|
tokenName: lrpDatum.iasset,
|
|
256
195
|
};
|
|
257
196
|
const rewardAssetsAmt = assetClassValueOf(lrpUtxo.assets, rewardAssetClass);
|
|
@@ -301,8 +240,7 @@ export async function adjustLrp(
|
|
|
301
240
|
export async function claimLrp(
|
|
302
241
|
lucid: LucidEvolution,
|
|
303
242
|
lrpOutRef: OutRef,
|
|
304
|
-
|
|
305
|
-
lrpParams: LRPParams,
|
|
243
|
+
sysParams: SystemParams,
|
|
306
244
|
): Promise<TxBuilder> {
|
|
307
|
-
return adjustLrp(lucid, lrpOutRef, 0n,
|
|
245
|
+
return adjustLrp(lucid, lrpOutRef, 0n, sysParams);
|
|
308
246
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { Data, Datum, Redeemer } from '@lucid-evolution/lucid';
|
|
1
|
+
import { Data, Datum, Redeemer, UTxO } from '@lucid-evolution/lucid';
|
|
2
2
|
import { AssetClassSchema, OutputReferenceSchema } from '../../types/generic';
|
|
3
3
|
import { OnChainDecimalSchema } from '../../types/on-chain-decimal';
|
|
4
|
+
import { option as O, function as F } from 'fp-ts';
|
|
4
5
|
|
|
5
6
|
export const LRPParamsSchema = Data.Object({
|
|
6
7
|
versionRecordToken: AssetClassSchema,
|
|
@@ -42,8 +43,21 @@ export const LRPRedeemerSchema = Data.Enum([
|
|
|
42
43
|
export type LRPRedeemer = Data.Static<typeof LRPRedeemerSchema>;
|
|
43
44
|
const LRPRedeemer = LRPRedeemerSchema as unknown as LRPRedeemer;
|
|
44
45
|
|
|
45
|
-
export function parseLrpDatum(datum: Datum): LRPDatum {
|
|
46
|
-
|
|
46
|
+
export function parseLrpDatum(datum: Datum): O.Option<LRPDatum> {
|
|
47
|
+
try {
|
|
48
|
+
return O.some(Data.from<LRPDatum>(datum, LRPDatum));
|
|
49
|
+
} catch (_) {
|
|
50
|
+
return O.none;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function parseLrpDatumOrThrow(datum: Datum): LRPDatum {
|
|
55
|
+
return F.pipe(
|
|
56
|
+
parseLrpDatum(datum),
|
|
57
|
+
O.match(() => {
|
|
58
|
+
throw new Error('Expected an LRP datum.');
|
|
59
|
+
}, F.identity),
|
|
60
|
+
);
|
|
47
61
|
}
|
|
48
62
|
|
|
49
63
|
export function serialiseLrpDatum(datum: LRPDatum): Datum {
|
|
@@ -57,3 +71,5 @@ export function serialiseLrpRedeemer(redeemer: LRPRedeemer): Redeemer {
|
|
|
57
71
|
export function castLrpParams(params: LRPParams): Data {
|
|
58
72
|
return Data.castTo(params, LRPParams);
|
|
59
73
|
}
|
|
74
|
+
|
|
75
|
+
export type LrpOutput = { datum: LRPDatum; utxo: UTxO };
|
|
@@ -461,10 +461,6 @@ export async function processSpRequest(
|
|
|
461
461
|
newPoolSum,
|
|
462
462
|
);
|
|
463
463
|
|
|
464
|
-
console.log('balanceChange', balanceChange);
|
|
465
|
-
console.log('withdrawalFee', withdrawalFee);
|
|
466
|
-
console.log('rewardLovelacesFee', rewardLovelacesFee);
|
|
467
|
-
console.log('reward', reward);
|
|
468
464
|
if (rewardLovelacesFee > 0n) {
|
|
469
465
|
await collectorFeeTx(
|
|
470
466
|
rewardLovelacesFee,
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
} from './types-new';
|
|
16
16
|
import { createScriptAddress } from '../../utils/lucid-utils';
|
|
17
17
|
import { mkStakingValidatorFromSP } from './scripts';
|
|
18
|
+
import { OCD_DECIMAL_UNIT } from '../../types/on-chain-decimal';
|
|
18
19
|
|
|
19
20
|
export type StakingPositionOutput = {
|
|
20
21
|
utxo: UTxO;
|
|
@@ -114,3 +115,13 @@ export function findStakingPositionByOutRef(
|
|
|
114
115
|
return result;
|
|
115
116
|
});
|
|
116
117
|
}
|
|
118
|
+
|
|
119
|
+
export const rewardSnapshotPrecision = OCD_DECIMAL_UNIT * OCD_DECIMAL_UNIT;
|
|
120
|
+
|
|
121
|
+
export function distributeReward(
|
|
122
|
+
snapshotAda: bigint,
|
|
123
|
+
adaReward: bigint,
|
|
124
|
+
totalStake: bigint,
|
|
125
|
+
): bigint {
|
|
126
|
+
return snapshotAda + (adaReward * rewardSnapshotPrecision) / totalStake;
|
|
127
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
addAssets,
|
|
2
3
|
Constr,
|
|
3
4
|
Data,
|
|
4
5
|
fromHex,
|
|
@@ -12,19 +13,25 @@ import {
|
|
|
12
13
|
fromSystemParamsScriptRef,
|
|
13
14
|
SystemParams,
|
|
14
15
|
} from '../../types/system-params';
|
|
15
|
-
import { addrDetails } from '../../utils/lucid-utils';
|
|
16
|
+
import { addrDetails, getInlineDatumOrThrow } from '../../utils/lucid-utils';
|
|
16
17
|
import {
|
|
18
|
+
distributeReward,
|
|
17
19
|
findStakingManager,
|
|
18
20
|
findStakingManagerByOutRef,
|
|
19
21
|
findStakingPositionByOutRef,
|
|
22
|
+
rewardSnapshotPrecision,
|
|
20
23
|
updateStakingLockedAmount,
|
|
21
24
|
} from './helpers';
|
|
22
25
|
import {
|
|
26
|
+
parseStakingManagerDatum,
|
|
23
27
|
serialiseStakingDatum,
|
|
24
28
|
StakingManager,
|
|
25
29
|
StakingPosition,
|
|
26
30
|
} from './types-new';
|
|
27
31
|
import { matchSingle } from '../../utils/utils';
|
|
32
|
+
import { serialiseStakingRedeemer } from './types';
|
|
33
|
+
import { serialiseCollectorRedeemer } from '../collector/types';
|
|
34
|
+
import { mkLovelacesOf } from '../../utils/value-helpers';
|
|
28
35
|
|
|
29
36
|
export async function openStakingPosition(
|
|
30
37
|
amount: bigint,
|
|
@@ -147,7 +154,7 @@ export async function adjustStakingPosition(
|
|
|
147
154
|
const oldSnapshotAda = stakingPositionOut.datum.positionSnapshot.snapshotAda;
|
|
148
155
|
const adaReward =
|
|
149
156
|
((currentSnapshotAda - oldSnapshotAda) * existingIndyAmount) /
|
|
150
|
-
|
|
157
|
+
rewardSnapshotPrecision;
|
|
151
158
|
|
|
152
159
|
const newLockedAmount = updateStakingLockedAmount(
|
|
153
160
|
stakingPositionOut.datum.lockedAmount,
|
|
@@ -158,8 +165,16 @@ export async function adjustStakingPosition(
|
|
|
158
165
|
.newTx()
|
|
159
166
|
.validFrom(Date.now())
|
|
160
167
|
.readFrom([stakingRefScriptUtxo])
|
|
161
|
-
.collectFrom(
|
|
162
|
-
|
|
168
|
+
.collectFrom(
|
|
169
|
+
[stakingPositionOut.utxo],
|
|
170
|
+
serialiseStakingRedeemer({
|
|
171
|
+
AdjustStakedAmount: { adjustAmount: amount },
|
|
172
|
+
}),
|
|
173
|
+
)
|
|
174
|
+
.collectFrom(
|
|
175
|
+
[stakingManagerOut.utxo],
|
|
176
|
+
serialiseStakingRedeemer('UpdateTotalStake'),
|
|
177
|
+
)
|
|
163
178
|
.pay.ToContract(
|
|
164
179
|
stakingManagerOut.utxo.address,
|
|
165
180
|
{
|
|
@@ -266,3 +281,78 @@ export async function closeStakingPosition(
|
|
|
266
281
|
)
|
|
267
282
|
.addSignerKey(toHex(stakingPositionOut.datum.owner));
|
|
268
283
|
}
|
|
284
|
+
|
|
285
|
+
const MIN_UTXO_AMOUNT = 2_000_000n;
|
|
286
|
+
|
|
287
|
+
export async function distributeAda(
|
|
288
|
+
stakingManagerRef: OutRef,
|
|
289
|
+
collectorRefs: OutRef[],
|
|
290
|
+
params: SystemParams,
|
|
291
|
+
lucid: LucidEvolution,
|
|
292
|
+
): Promise<TxBuilder> {
|
|
293
|
+
const [stakingManagerUtxo] = await lucid.utxosByOutRef([stakingManagerRef]);
|
|
294
|
+
const stakingManagerDatum = parseStakingManagerDatum(
|
|
295
|
+
getInlineDatumOrThrow(stakingManagerUtxo),
|
|
296
|
+
);
|
|
297
|
+
const collectorUtxos = (await lucid.utxosByOutRef(collectorRefs))
|
|
298
|
+
.filter((utxo) => utxo.datum && utxo.datum === Data.void())
|
|
299
|
+
.filter((utxo) => utxo.assets.lovelace > MIN_UTXO_AMOUNT);
|
|
300
|
+
|
|
301
|
+
if (collectorUtxos.length === 0) {
|
|
302
|
+
throw new Error('No available collectors found');
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
const adaRewardCollected = collectorUtxos.reduce(
|
|
306
|
+
(acc, utxo) => acc + utxo.assets.lovelace - MIN_UTXO_AMOUNT,
|
|
307
|
+
0n,
|
|
308
|
+
);
|
|
309
|
+
const newSnapshot = distributeReward(
|
|
310
|
+
stakingManagerDatum.managerSnapshot.snapshotAda,
|
|
311
|
+
adaRewardCollected,
|
|
312
|
+
stakingManagerDatum.totalStake,
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
const stakingRefScriptUtxo = matchSingle(
|
|
316
|
+
await lucid.utxosByOutRef([
|
|
317
|
+
fromSystemParamsScriptRef(params.scriptReferences.stakingValidatorRef),
|
|
318
|
+
]),
|
|
319
|
+
(_) => new Error('Expected a single staking Ref Script UTXO'),
|
|
320
|
+
);
|
|
321
|
+
|
|
322
|
+
const collectorRefScriptUtxo = matchSingle(
|
|
323
|
+
await lucid.utxosByOutRef([
|
|
324
|
+
fromSystemParamsScriptRef(params.scriptReferences.collectorValidatorRef),
|
|
325
|
+
]),
|
|
326
|
+
(_) => new Error('Expected a single staking Ref Script UTXO'),
|
|
327
|
+
);
|
|
328
|
+
|
|
329
|
+
const tx = lucid
|
|
330
|
+
.newTx()
|
|
331
|
+
.readFrom([stakingRefScriptUtxo, collectorRefScriptUtxo])
|
|
332
|
+
.collectFrom([stakingManagerUtxo], serialiseStakingRedeemer('Distribute'))
|
|
333
|
+
.collectFrom(
|
|
334
|
+
collectorUtxos,
|
|
335
|
+
serialiseCollectorRedeemer('DistributeToStakers'),
|
|
336
|
+
)
|
|
337
|
+
.pay.ToContract(
|
|
338
|
+
stakingManagerUtxo.address,
|
|
339
|
+
{
|
|
340
|
+
kind: 'inline',
|
|
341
|
+
value: serialiseStakingDatum({
|
|
342
|
+
...stakingManagerDatum,
|
|
343
|
+
managerSnapshot: { snapshotAda: newSnapshot },
|
|
344
|
+
}),
|
|
345
|
+
},
|
|
346
|
+
addAssets(stakingManagerUtxo.assets, mkLovelacesOf(adaRewardCollected)),
|
|
347
|
+
);
|
|
348
|
+
|
|
349
|
+
for (const collectorUtxo of collectorUtxos) {
|
|
350
|
+
tx.pay.ToContract(
|
|
351
|
+
collectorUtxo.address,
|
|
352
|
+
{ kind: 'inline', value: Data.void() },
|
|
353
|
+
mkLovelacesOf(MIN_UTXO_AMOUNT),
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return tx;
|
|
358
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -11,13 +11,14 @@ export * from './contracts/gov/types';
|
|
|
11
11
|
export * from './contracts/stability-pool/transactions';
|
|
12
12
|
export * from './contracts/stability-pool/types-new';
|
|
13
13
|
export * from './contracts/staking/transactions';
|
|
14
|
+
export * from './contracts/staking/types';
|
|
15
|
+
export * from './contracts/staking/types-new';
|
|
14
16
|
export * from './contracts/interest-oracle/transactions';
|
|
15
17
|
export * from './contracts/interest-oracle/types';
|
|
16
18
|
export * from './contracts/interest-oracle/scripts';
|
|
17
19
|
export * from './contracts/version-registry/types';
|
|
18
20
|
export * from './contracts/version-registry/scripts';
|
|
19
21
|
export * from './contracts/treasury/transactions';
|
|
20
|
-
export * from './utils/utils';
|
|
21
22
|
export * from './utils/lucid-utils';
|
|
22
23
|
export * from './contracts/stability-pool/helpers';
|
|
23
24
|
export * from './utils/time-helpers';
|
|
@@ -28,14 +29,18 @@ export * from './contracts/execute/types';
|
|
|
28
29
|
export * from './contracts/execute/scripts';
|
|
29
30
|
export * from './contracts/price-oracle/types';
|
|
30
31
|
export * from './contracts/stability-pool/types';
|
|
31
|
-
export * from './contracts/lrp/types';
|
|
32
32
|
export * from './contracts/poll/types-poll-shard';
|
|
33
33
|
export * from './contracts/poll/types-poll-manager';
|
|
34
34
|
export * from './types/generic';
|
|
35
35
|
export * from './types/system-params';
|
|
36
|
+
export * from './contracts/lrp/helpers';
|
|
36
37
|
export * from './contracts/lrp/transactions';
|
|
37
38
|
export * from './contracts/lrp/scripts';
|
|
39
|
+
export * from './contracts/lrp/types';
|
|
38
40
|
export * from './utils/helper-txs';
|
|
39
41
|
export * from './contracts/one-shot/transactions';
|
|
40
42
|
export * from './utils/utils';
|
|
43
|
+
export * from './utils/array-utils';
|
|
41
44
|
export * from './utils/value-helpers';
|
|
45
|
+
export * from './contracts/leverage/transactions';
|
|
46
|
+
export * from './contracts/leverage/helpers';
|
|
@@ -13,6 +13,10 @@ export function ocdCeil(a: OnChainDecimal): bigint {
|
|
|
13
13
|
return a.getOnChainInt > whole * OCD_DECIMAL_UNIT ? whole + 1n : whole;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
export function ocdFloor(a: OnChainDecimal): bigint {
|
|
17
|
+
return a.getOnChainInt / OCD_DECIMAL_UNIT;
|
|
18
|
+
}
|
|
19
|
+
|
|
16
20
|
export function ocdNegate(a: OnChainDecimal): OnChainDecimal {
|
|
17
21
|
return { getOnChainInt: -a.getOnChainInt };
|
|
18
22
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { array as A, ord as Ord } from 'fp-ts';
|
|
2
|
+
|
|
3
|
+
export function shuffle<T>(arr: T[]): T[] {
|
|
4
|
+
const source = [...arr];
|
|
5
|
+
for (let i = source.length - 1; i > 0; i--) {
|
|
6
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
7
|
+
[source[i], source[j]] = [source[j], source[i]];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
return source;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The parameter `arr` should be sorted for correct results.
|
|
15
|
+
*/
|
|
16
|
+
export function insertSorted<T>(arr: T[], item: T, ord: Ord.Ord<T>): T[] {
|
|
17
|
+
if (arr.length === 0) {
|
|
18
|
+
return [item];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const arrOrd = ord.compare(arr[0], arr[arr.length - 1]);
|
|
22
|
+
// Array containing the same items
|
|
23
|
+
if (arrOrd === 0) {
|
|
24
|
+
if (ord.compare(arr[0], item) === -1) {
|
|
25
|
+
return [...arr, item];
|
|
26
|
+
} else {
|
|
27
|
+
return [item, ...arr];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// TODO: could be improved with binary search
|
|
32
|
+
for (let i = 0; i < arr.length; i++) {
|
|
33
|
+
if (ord.compare(arr[i], item) !== arrOrd) {
|
|
34
|
+
return [...A.takeLeft(i)(arr), item, ...A.takeRight(arr.length - i)(arr)];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return [...arr, item];
|
|
39
|
+
}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import Decimal from 'decimal.js';
|
|
2
|
+
import { array as A, ord as Ord } from 'fp-ts';
|
|
3
|
+
|
|
1
4
|
export function bigintMax(a: bigint, b: bigint): bigint {
|
|
2
5
|
return a > b ? a : b;
|
|
3
6
|
}
|
|
@@ -5,3 +8,16 @@ export function bigintMax(a: bigint, b: bigint): bigint {
|
|
|
5
8
|
export function bigintMin(a: bigint, b: bigint): bigint {
|
|
6
9
|
return a < b ? a : b;
|
|
7
10
|
}
|
|
11
|
+
|
|
12
|
+
export function sum(arr: bigint[]): bigint {
|
|
13
|
+
return A.reduce<bigint, bigint>(0n, (acc, val) => acc + val)(arr);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function fromDecimal(val: Decimal): bigint {
|
|
17
|
+
return BigInt(val.toString());
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const BigIntOrd: Ord.Ord<bigint> = {
|
|
21
|
+
equals: (x, y) => x === y,
|
|
22
|
+
compare: (first, second) => (first < second ? -1 : first > second ? 1 : 0),
|
|
23
|
+
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { expect, test } from 'vitest';
|
|
2
|
+
import { insertSorted, shuffle } from '../src/utils/array-utils';
|
|
3
|
+
import { BigIntOrd } from '../src/utils/bigint-utils';
|
|
4
|
+
import { ord as Ord, number as Num, array as A } from 'fp-ts';
|
|
5
|
+
|
|
6
|
+
test('Shuffle', () => {
|
|
7
|
+
const arr = [1, 2, 34, 45, -1, 20, 35];
|
|
8
|
+
const shuffled = shuffle(arr);
|
|
9
|
+
|
|
10
|
+
expect(shuffled.length).toBe(arr.length);
|
|
11
|
+
expect(A.sort(Num.Ord)(shuffled)).toEqual(A.sort(Num.Ord)(arr));
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('insert sorted 1', () => {
|
|
15
|
+
const arr = [0n, 2n, 3n];
|
|
16
|
+
expect(insertSorted(arr, 1n, BigIntOrd)).toEqual([0n, 1n, 2n, 3n]);
|
|
17
|
+
});
|
|
18
|
+
test('insert sorted 2', () => {
|
|
19
|
+
const arr = [0n, 2n, 4n];
|
|
20
|
+
expect(insertSorted(arr, 3n, BigIntOrd)).toEqual([0n, 2n, 3n, 4n]);
|
|
21
|
+
});
|
|
22
|
+
test('insert sorted at start', () => {
|
|
23
|
+
const arr = [0n, 2n, 3n];
|
|
24
|
+
expect(insertSorted(arr, -1n, BigIntOrd)).toEqual([-1n, 0n, 2n, 3n]);
|
|
25
|
+
});
|
|
26
|
+
test('insert sorted at end', () => {
|
|
27
|
+
const arr = [0n, 2n, 3n];
|
|
28
|
+
expect(insertSorted(arr, 5n, BigIntOrd)).toEqual([0n, 2n, 3n, 5n]);
|
|
29
|
+
});
|
|
30
|
+
test('insert sorted at start when array all equal', () => {
|
|
31
|
+
const arr = [0n, 0n, 0n];
|
|
32
|
+
expect(insertSorted(arr, -1n, BigIntOrd)).toEqual([-1n, 0n, 0n, 0n]);
|
|
33
|
+
});
|
|
34
|
+
test('insert sorted at end when array all equal', () => {
|
|
35
|
+
const arr = [0n, 0n, 0n];
|
|
36
|
+
expect(insertSorted(arr, 1n, BigIntOrd)).toEqual([0n, 0n, 0n, 1n]);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test('insert sorted reversed 1', () => {
|
|
40
|
+
const arr = [3n, 2n, 0n];
|
|
41
|
+
expect(insertSorted(arr, 1n, Ord.reverse(BigIntOrd))).toEqual([
|
|
42
|
+
3n,
|
|
43
|
+
2n,
|
|
44
|
+
1n,
|
|
45
|
+
0n,
|
|
46
|
+
]);
|
|
47
|
+
});
|
|
48
|
+
test('insert sorted reversed 2', () => {
|
|
49
|
+
const arr = [4n, 2n, 0n];
|
|
50
|
+
expect(insertSorted(arr, 3n, Ord.reverse(BigIntOrd))).toEqual([
|
|
51
|
+
4n,
|
|
52
|
+
3n,
|
|
53
|
+
2n,
|
|
54
|
+
0n,
|
|
55
|
+
]);
|
|
56
|
+
});
|
|
57
|
+
test('insert sorted eversed at start', () => {
|
|
58
|
+
const arr = [3n, 2n, 0n];
|
|
59
|
+
expect(insertSorted(arr, 4n, Ord.reverse(BigIntOrd))).toEqual([
|
|
60
|
+
4n,
|
|
61
|
+
3n,
|
|
62
|
+
2n,
|
|
63
|
+
0n,
|
|
64
|
+
]);
|
|
65
|
+
});
|
|
66
|
+
test('insert sorted reversed at end', () => {
|
|
67
|
+
const arr = [3n, 2n, 0n];
|
|
68
|
+
expect(insertSorted(arr, -1n, Ord.reverse(BigIntOrd))).toEqual([
|
|
69
|
+
3n,
|
|
70
|
+
2n,
|
|
71
|
+
0n,
|
|
72
|
+
-1n,
|
|
73
|
+
]);
|
|
74
|
+
});
|
|
75
|
+
test('insert sorted reversed at end when array all equal', () => {
|
|
76
|
+
const arr = [0n, 0n, 0n];
|
|
77
|
+
expect(insertSorted(arr, -1n, Ord.reverse(BigIntOrd))).toEqual([
|
|
78
|
+
0n,
|
|
79
|
+
0n,
|
|
80
|
+
0n,
|
|
81
|
+
-1n,
|
|
82
|
+
]);
|
|
83
|
+
});
|
|
84
|
+
test('insert sorted reversed at start when array all equal', () => {
|
|
85
|
+
const arr = [0n, 0n, 0n];
|
|
86
|
+
expect(insertSorted(arr, 1n, Ord.reverse(BigIntOrd))).toEqual([
|
|
87
|
+
1n,
|
|
88
|
+
0n,
|
|
89
|
+
0n,
|
|
90
|
+
0n,
|
|
91
|
+
]);
|
|
92
|
+
});
|