@indigo-labs/indigo-sdk 0.1.8 → 0.1.9
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 +8 -8
- package/dist/index.d.ts +8 -8
- package/dist/index.js +326 -315
- package/dist/index.mjs +78 -64
- package/package.json +1 -2
- package/src/contracts/cdp.ts +54 -47
- package/src/contracts/lrp.ts +9 -16
- package/tests/lrp.test.ts +0 -8
- package/tests/stability-pool.test.ts +26 -3
package/dist/index.mjs
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
credentialToAddress as credentialToAddress3,
|
|
6
6
|
Data as Data10,
|
|
7
7
|
fromText as fromText4,
|
|
8
|
+
slotToUnixTime as slotToUnixTime2,
|
|
8
9
|
validatorToAddress as validatorToAddress3,
|
|
9
10
|
validatorToScriptHash as validatorToScriptHash3
|
|
10
11
|
} from "@lucid-evolution/lucid";
|
|
@@ -602,9 +603,30 @@ function calculateAccruedInterest(now, unitaryInterestSnapshot, mintedAmount, in
|
|
|
602
603
|
}
|
|
603
604
|
}
|
|
604
605
|
|
|
606
|
+
// src/helpers/price-oracle-helpers.ts
|
|
607
|
+
import {
|
|
608
|
+
slotToUnixTime,
|
|
609
|
+
unixTimeToSlot
|
|
610
|
+
} from "@lucid-evolution/lucid";
|
|
611
|
+
function oracleExpirationAwareValidity(currentSlot, biasTime, oracleExpiration, network) {
|
|
612
|
+
const validateFrom = slotToUnixTime(network, currentSlot - 1);
|
|
613
|
+
const defaultValidateTo = validateFrom + biasTime;
|
|
614
|
+
const cappedValidateTo = slotToUnixTime(
|
|
615
|
+
network,
|
|
616
|
+
unixTimeToSlot(network, oracleExpiration) - 1
|
|
617
|
+
);
|
|
618
|
+
const isOracleActuallyExpired = cappedValidateTo <= validateFrom;
|
|
619
|
+
return {
|
|
620
|
+
validFrom: validateFrom,
|
|
621
|
+
validTo: isOracleActuallyExpired ? defaultValidateTo : Math.min(defaultValidateTo, cappedValidateTo)
|
|
622
|
+
};
|
|
623
|
+
}
|
|
624
|
+
|
|
605
625
|
// src/contracts/cdp.ts
|
|
606
626
|
var CDPContract = class _CDPContract {
|
|
607
|
-
static async openPosition(asset, collateralAmount, mintedAmount, params, lucid, assetRef, priceOracleRef, interestOracleRef, cdpCreatorRef, collectorRef
|
|
627
|
+
static async openPosition(asset, collateralAmount, mintedAmount, params, lucid, currentSlot, assetRef, priceOracleRef, interestOracleRef, cdpCreatorRef, collectorRef) {
|
|
628
|
+
const network = lucid.config().network;
|
|
629
|
+
const currentTime = BigInt(slotToUnixTime2(network, currentSlot));
|
|
608
630
|
const [pkh, skh] = await addrDetails(lucid);
|
|
609
631
|
const assetOut = await (assetRef ? IAssetHelpers.findIAssetByRef(assetRef, lucid) : IAssetHelpers.findIAssetByName(asset, params, lucid));
|
|
610
632
|
if (!assetOut || !assetOut.datum) throw new Error("Unable to find IAsset");
|
|
@@ -630,7 +652,7 @@ var CDPContract = class _CDPContract {
|
|
|
630
652
|
);
|
|
631
653
|
const cdpCreatorOut = getRandomElement(
|
|
632
654
|
cdpCreatorRef ? await lucid.utxosByOutRef([cdpCreatorRef]) : await lucid.utxosAtWithUnit(
|
|
633
|
-
credentialToAddress3(
|
|
655
|
+
credentialToAddress3(network, {
|
|
634
656
|
type: "Script",
|
|
635
657
|
hash: params.validatorHashes.cdpCreatorHash
|
|
636
658
|
}),
|
|
@@ -642,7 +664,7 @@ var CDPContract = class _CDPContract {
|
|
|
642
664
|
cdpOwner: pkh.hash,
|
|
643
665
|
minted: mintedAmount,
|
|
644
666
|
collateral: collateralAmount,
|
|
645
|
-
currentTime
|
|
667
|
+
currentTime
|
|
646
668
|
}
|
|
647
669
|
});
|
|
648
670
|
const cdpCreatorScriptRefUtxo = await scriptRef(
|
|
@@ -656,7 +678,7 @@ var CDPContract = class _CDPContract {
|
|
|
656
678
|
};
|
|
657
679
|
cdpValue[cdpToken] = 1n;
|
|
658
680
|
const newSnapshot = calculateUnitaryInterestSinceOracleLastUpdated(
|
|
659
|
-
|
|
681
|
+
currentTime,
|
|
660
682
|
interestOracleDatum
|
|
661
683
|
) + interestOracleDatum.unitaryInterest;
|
|
662
684
|
const cdpDatum = {
|
|
@@ -665,7 +687,7 @@ var CDPContract = class _CDPContract {
|
|
|
665
687
|
mintedAmt: mintedAmount,
|
|
666
688
|
cdpFees: {
|
|
667
689
|
ActiveCDPInterestTracking: {
|
|
668
|
-
lastSettled:
|
|
690
|
+
lastSettled: currentTime,
|
|
669
691
|
unitaryInterestSnapshot: newSnapshot
|
|
670
692
|
}
|
|
671
693
|
}
|
|
@@ -687,10 +709,12 @@ var CDPContract = class _CDPContract {
|
|
|
687
709
|
BigInt(assetOut.datum.debtMintingFeePercentage.getOnChainInt),
|
|
688
710
|
mintedAmount * oracleDatum.price.getOnChainInt / 1000000n
|
|
689
711
|
);
|
|
690
|
-
const
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
712
|
+
const txValidity = oracleExpirationAwareValidity(
|
|
713
|
+
currentSlot,
|
|
714
|
+
Number(params.cdpCreatorParams.biasTime),
|
|
715
|
+
Number(oracleDatum.expiration),
|
|
716
|
+
network
|
|
717
|
+
);
|
|
694
718
|
const tx = lucid.newTx().collectFrom([cdpCreatorOut], Data10.to(cdpCreatorRedeemer)).readFrom([cdpCreatorScriptRefUtxo]).pay.ToContract(
|
|
695
719
|
cdpAddress,
|
|
696
720
|
{ kind: "inline", value: serialiseCDPDatum(cdpDatum) },
|
|
@@ -699,7 +723,7 @@ var CDPContract = class _CDPContract {
|
|
|
699
723
|
cdpCreatorOut.address,
|
|
700
724
|
{ kind: "inline", value: cdpCreatorOut.datum },
|
|
701
725
|
cdpCreatorOut.assets
|
|
702
|
-
).readFrom([oracleOut, interestOracleOut, assetOut.utxo]).mintAssets(cdpTokenMintValue, Data10.to(new Constr3(0, []))).readFrom([cdpAuthTokenScriptRefUtxo]).mintAssets(iassetTokenMintValue, Data10.to(new Constr3(0, []))).readFrom([iAssetTokenScriptRefUtxo]).addSignerKey(pkh.hash).validFrom(
|
|
726
|
+
).readFrom([oracleOut, interestOracleOut, assetOut.utxo]).mintAssets(cdpTokenMintValue, Data10.to(new Constr3(0, []))).readFrom([cdpAuthTokenScriptRefUtxo]).mintAssets(iassetTokenMintValue, Data10.to(new Constr3(0, []))).readFrom([iAssetTokenScriptRefUtxo]).addSignerKey(pkh.hash).validFrom(txValidity.validFrom).validTo(txValidity.validTo);
|
|
703
727
|
if (debtMintingFee > 0) {
|
|
704
728
|
await CollectorContract.feeTx(
|
|
705
729
|
debtMintingFee,
|
|
@@ -711,13 +735,14 @@ var CDPContract = class _CDPContract {
|
|
|
711
735
|
}
|
|
712
736
|
return tx;
|
|
713
737
|
}
|
|
714
|
-
static async deposit(cdpRef, amount, params, lucid, assetRef, priceOracleRef, interestOracleRef, collectorRef, govRef, treasuryRef) {
|
|
738
|
+
static async deposit(cdpRef, amount, params, lucid, currentSlot, assetRef, priceOracleRef, interestOracleRef, collectorRef, govRef, treasuryRef) {
|
|
715
739
|
return _CDPContract.adjust(
|
|
716
740
|
cdpRef,
|
|
717
741
|
amount,
|
|
718
742
|
0n,
|
|
719
743
|
params,
|
|
720
744
|
lucid,
|
|
745
|
+
currentSlot,
|
|
721
746
|
assetRef,
|
|
722
747
|
priceOracleRef,
|
|
723
748
|
interestOracleRef,
|
|
@@ -726,13 +751,14 @@ var CDPContract = class _CDPContract {
|
|
|
726
751
|
treasuryRef
|
|
727
752
|
);
|
|
728
753
|
}
|
|
729
|
-
static async withdraw(cdpRef, amount, params, lucid, assetRef, priceOracleRef, interestOracleRef, collectorRef, govRef, treasuryRef) {
|
|
754
|
+
static async withdraw(cdpRef, amount, params, lucid, currentSlot, assetRef, priceOracleRef, interestOracleRef, collectorRef, govRef, treasuryRef) {
|
|
730
755
|
return _CDPContract.adjust(
|
|
731
756
|
cdpRef,
|
|
732
757
|
-amount,
|
|
733
758
|
0n,
|
|
734
759
|
params,
|
|
735
760
|
lucid,
|
|
761
|
+
currentSlot,
|
|
736
762
|
assetRef,
|
|
737
763
|
priceOracleRef,
|
|
738
764
|
interestOracleRef,
|
|
@@ -741,13 +767,14 @@ var CDPContract = class _CDPContract {
|
|
|
741
767
|
treasuryRef
|
|
742
768
|
);
|
|
743
769
|
}
|
|
744
|
-
static async mint(cdpRef, amount, params, lucid, assetRef, priceOracleRef, interestOracleRef, collectorRef, govRef, treasuryRef) {
|
|
770
|
+
static async mint(cdpRef, amount, params, lucid, currentSlot, assetRef, priceOracleRef, interestOracleRef, collectorRef, govRef, treasuryRef) {
|
|
745
771
|
return _CDPContract.adjust(
|
|
746
772
|
cdpRef,
|
|
747
773
|
0n,
|
|
748
774
|
amount,
|
|
749
775
|
params,
|
|
750
776
|
lucid,
|
|
777
|
+
currentSlot,
|
|
751
778
|
assetRef,
|
|
752
779
|
priceOracleRef,
|
|
753
780
|
interestOracleRef,
|
|
@@ -756,13 +783,14 @@ var CDPContract = class _CDPContract {
|
|
|
756
783
|
treasuryRef
|
|
757
784
|
);
|
|
758
785
|
}
|
|
759
|
-
static async burn(cdpRef, amount, params, lucid, assetRef, priceOracleRef, interestOracleRef, collectorRef, govRef, treasuryRef) {
|
|
786
|
+
static async burn(cdpRef, amount, params, lucid, currentSlot, assetRef, priceOracleRef, interestOracleRef, collectorRef, govRef, treasuryRef) {
|
|
760
787
|
return _CDPContract.adjust(
|
|
761
788
|
cdpRef,
|
|
762
789
|
0n,
|
|
763
790
|
-amount,
|
|
764
791
|
params,
|
|
765
792
|
lucid,
|
|
793
|
+
currentSlot,
|
|
766
794
|
assetRef,
|
|
767
795
|
priceOracleRef,
|
|
768
796
|
interestOracleRef,
|
|
@@ -771,9 +799,10 @@ var CDPContract = class _CDPContract {
|
|
|
771
799
|
treasuryRef
|
|
772
800
|
);
|
|
773
801
|
}
|
|
774
|
-
static async adjust(cdpRef, collateralAmount, mintAmount, params, lucid, assetRef, priceOracleRef, interestOracleRef, collectorRef, govRef, treasuryRef) {
|
|
802
|
+
static async adjust(cdpRef, collateralAmount, mintAmount, params, lucid, currentSlot, assetRef, priceOracleRef, interestOracleRef, collectorRef, govRef, treasuryRef) {
|
|
803
|
+
const network = lucid.config().network;
|
|
775
804
|
const [pkh, _] = await addrDetails(lucid);
|
|
776
|
-
const
|
|
805
|
+
const currentTime = BigInt(slotToUnixTime2(network, currentSlot));
|
|
777
806
|
const cdp = (await lucid.utxosByOutRef([cdpRef]))[0];
|
|
778
807
|
if (!cdp.datum) throw new Error("Unable to find CDP Datum");
|
|
779
808
|
const cdpDatum = parseCDPDatum(cdp.datum);
|
|
@@ -800,14 +829,14 @@ var CDPContract = class _CDPContract {
|
|
|
800
829
|
);
|
|
801
830
|
const tx = lucid.newTx().collectFrom(
|
|
802
831
|
[cdp],
|
|
803
|
-
Data10.to(new Constr3(0, [
|
|
832
|
+
Data10.to(new Constr3(0, [currentTime, mintAmount, collateralAmount]))
|
|
804
833
|
).readFrom([iAsset.utxo, gov, cdpScriptRefUtxo]).addSignerKey(pkh.hash);
|
|
805
834
|
if (!cdp.datum) throw new Error("Unable to find CDP Datum");
|
|
806
835
|
const cdpD = parseCDPDatum(cdp.datum);
|
|
807
836
|
if (!("ActiveCDPInterestTracking" in cdpD.cdpFees))
|
|
808
837
|
throw new Error("Invalid CDP Fees");
|
|
809
838
|
const newSnapshot = calculateUnitaryInterestSinceOracleLastUpdated(
|
|
810
|
-
|
|
839
|
+
currentTime,
|
|
811
840
|
interestOracleDatum
|
|
812
841
|
) + interestOracleDatum.unitaryInterest;
|
|
813
842
|
const cdpD_ = {
|
|
@@ -815,7 +844,7 @@ var CDPContract = class _CDPContract {
|
|
|
815
844
|
mintedAmt: cdpD.mintedAmt + mintAmount,
|
|
816
845
|
cdpFees: {
|
|
817
846
|
ActiveCDPInterestTracking: {
|
|
818
|
-
lastSettled:
|
|
847
|
+
lastSettled: currentTime,
|
|
819
848
|
unitaryInterestSnapshot: newSnapshot
|
|
820
849
|
}
|
|
821
850
|
}
|
|
@@ -837,11 +866,13 @@ var CDPContract = class _CDPContract {
|
|
|
837
866
|
return Promise.reject(new Error("Invalid oracle input"));
|
|
838
867
|
const od = parsePriceOracleDatum(oracleRefInput.datum);
|
|
839
868
|
if (!od) return Promise.reject(new Error("Invalid oracle input"));
|
|
840
|
-
const
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
869
|
+
const txValidity = oracleExpirationAwareValidity(
|
|
870
|
+
currentSlot,
|
|
871
|
+
Number(params.cdpCreatorParams.biasTime),
|
|
872
|
+
Number(od.expiration),
|
|
873
|
+
network
|
|
874
|
+
);
|
|
875
|
+
tx.readFrom([oracleRefInput]).validFrom(txValidity.validFrom).validTo(txValidity.validTo);
|
|
845
876
|
let fee = 0n;
|
|
846
877
|
if (collateralAmount < 0) {
|
|
847
878
|
fee += calculateFeeFromPercentage(
|
|
@@ -856,7 +887,7 @@ var CDPContract = class _CDPContract {
|
|
|
856
887
|
);
|
|
857
888
|
}
|
|
858
889
|
const interestPaymentAsset = calculateAccruedInterest(
|
|
859
|
-
|
|
890
|
+
currentTime,
|
|
860
891
|
cdpD.cdpFees.ActiveCDPInterestTracking.unitaryInterestSnapshot,
|
|
861
892
|
cdpD.mintedAmt,
|
|
862
893
|
cdpD.cdpFees.ActiveCDPInterestTracking.lastSettled,
|
|
@@ -897,9 +928,10 @@ var CDPContract = class _CDPContract {
|
|
|
897
928
|
}
|
|
898
929
|
return tx;
|
|
899
930
|
}
|
|
900
|
-
static async close(cdpRef, params, lucid, assetRef, priceOracleRef, interestOracleRef, collectorRef, govRef, treasuryRef) {
|
|
931
|
+
static async close(cdpRef, params, lucid, currentSlot, assetRef, priceOracleRef, interestOracleRef, collectorRef, govRef, treasuryRef) {
|
|
932
|
+
const network = lucid.config().network;
|
|
901
933
|
const [pkh, _] = await addrDetails(lucid);
|
|
902
|
-
const
|
|
934
|
+
const currentTime = BigInt(slotToUnixTime2(network, currentSlot));
|
|
903
935
|
const cdp = (await lucid.utxosByOutRef([cdpRef]))[0];
|
|
904
936
|
if (!cdp.datum) throw new Error("Unable to find CDP Datum");
|
|
905
937
|
const cdpDatum = parseCDPDatum(cdp.datum);
|
|
@@ -921,7 +953,7 @@ var CDPContract = class _CDPContract {
|
|
|
921
953
|
const interestOracleDatum = parseInterestOracleDatum(
|
|
922
954
|
interestOracleOut.datum
|
|
923
955
|
);
|
|
924
|
-
const tx = lucid.newTx().collectFrom([cdp], Data10.to(new Constr3(1, [
|
|
956
|
+
const tx = lucid.newTx().collectFrom([cdp], Data10.to(new Constr3(1, [currentTime]))).readFrom([iAsset.utxo, gov, cdpScriptRefUtxo]).addSignerKey(pkh.hash);
|
|
925
957
|
if (!cdp.datum) throw new Error("Unable to find CDP Datum");
|
|
926
958
|
const cdpD = parseCDPDatum(cdp.datum);
|
|
927
959
|
if (!("ActiveCDPInterestTracking" in cdpD.cdpFees))
|
|
@@ -935,14 +967,16 @@ var CDPContract = class _CDPContract {
|
|
|
935
967
|
if (!oracleRefInput.datum)
|
|
936
968
|
return Promise.reject(new Error("Invalid oracle input"));
|
|
937
969
|
const od = parsePriceOracleDatum(oracleRefInput.datum);
|
|
938
|
-
const
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
970
|
+
const txValidity = oracleExpirationAwareValidity(
|
|
971
|
+
currentSlot,
|
|
972
|
+
Number(params.cdpCreatorParams.biasTime),
|
|
973
|
+
Number(od.expiration),
|
|
974
|
+
network
|
|
975
|
+
);
|
|
976
|
+
tx.readFrom([oracleRefInput]).validFrom(txValidity.validFrom).validTo(txValidity.validTo);
|
|
943
977
|
let fee = 0n;
|
|
944
978
|
const interestPaymentAsset = calculateAccruedInterest(
|
|
945
|
-
|
|
979
|
+
currentTime,
|
|
946
980
|
cdpD.cdpFees.ActiveCDPInterestTracking.unitaryInterestSnapshot,
|
|
947
981
|
cdpD.mintedAmt,
|
|
948
982
|
cdpD.cdpFees.ActiveCDPInterestTracking.lastSettled,
|
|
@@ -2692,32 +2726,13 @@ function castLrpParams(params) {
|
|
|
2692
2726
|
|
|
2693
2727
|
// src/contracts/lrp.ts
|
|
2694
2728
|
import {
|
|
2695
|
-
addAssets as addAssets3
|
|
2729
|
+
addAssets as addAssets3,
|
|
2730
|
+
unixTimeToSlot as unixTimeToSlot2,
|
|
2731
|
+
slotToUnixTime as slotToUnixTime3
|
|
2696
2732
|
} from "@lucid-evolution/lucid";
|
|
2697
2733
|
import { match as match5, P as P5 } from "ts-pattern";
|
|
2698
2734
|
import { unzip, zip } from "fp-ts/lib/Array";
|
|
2699
2735
|
import { reduceWithIndex } from "fp-ts/lib/Array";
|
|
2700
|
-
|
|
2701
|
-
// src/helpers/price-oracle-helpers.ts
|
|
2702
|
-
import {
|
|
2703
|
-
slotToUnixTime,
|
|
2704
|
-
unixTimeToSlot
|
|
2705
|
-
} from "@lucid-evolution/lucid";
|
|
2706
|
-
function oracleExpirationAwareValidity(currentSlot, biasTime, oracleExpiration, network) {
|
|
2707
|
-
const validateFrom = slotToUnixTime(network, currentSlot - 1);
|
|
2708
|
-
const defaultValidateTo = validateFrom + biasTime;
|
|
2709
|
-
const cappedValidateTo = slotToUnixTime(
|
|
2710
|
-
network,
|
|
2711
|
-
unixTimeToSlot(network, oracleExpiration) - 1
|
|
2712
|
-
);
|
|
2713
|
-
const isOracleActuallyExpired = cappedValidateTo <= validateFrom;
|
|
2714
|
-
return {
|
|
2715
|
-
validFrom: validateFrom,
|
|
2716
|
-
validTo: isOracleActuallyExpired ? defaultValidateTo : Math.min(defaultValidateTo, cappedValidateTo)
|
|
2717
|
-
};
|
|
2718
|
-
}
|
|
2719
|
-
|
|
2720
|
-
// src/contracts/lrp.ts
|
|
2721
2736
|
var MIN_UTXO_COLLATERAL_AMT = 2000000n;
|
|
2722
2737
|
async function openLrp(assetTokenName, lovelacesAmt, maxPrice, lucid, lrpScriptHash, network, lrpStakeCredential) {
|
|
2723
2738
|
const [ownPkh, _] = await addrDetails(lucid);
|
|
@@ -2748,7 +2763,7 @@ async function cancelLrp(lrpOutRef, lrpRefScriptOutRef, lucid) {
|
|
|
2748
2763
|
);
|
|
2749
2764
|
return lucid.newTx().readFrom([lrpScriptRefUtxo]).collectFrom([lrpUtxo], serialiseLrpRedeemer("Cancel")).addSigner(ownAddr);
|
|
2750
2765
|
}
|
|
2751
|
-
async function redeemLrp(redemptionLrpsData, lrpRefScriptOutRef, priceOracleOutRef, iassetOutRef, lucid, lrpParams,
|
|
2766
|
+
async function redeemLrp(redemptionLrpsData, lrpRefScriptOutRef, priceOracleOutRef, iassetOutRef, lucid, lrpParams, network) {
|
|
2752
2767
|
const lrpScriptRefUtxo = matchSingle(
|
|
2753
2768
|
await lucid.utxosByOutRef([lrpRefScriptOutRef]),
|
|
2754
2769
|
(_2) => new Error("Expected a single LRP Ref Script UTXO")
|
|
@@ -2830,13 +2845,12 @@ async function redeemLrp(redemptionLrpsData, lrpRefScriptOutRef, priceOracleOutR
|
|
|
2830
2845
|
);
|
|
2831
2846
|
}
|
|
2832
2847
|
)(redemptionLrps);
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
);
|
|
2839
|
-
return lucid.newTx().validFrom(txValidity.validFrom).validTo(txValidity.validTo).readFrom([lrpScriptRefUtxo]).readFrom([iassetUtxo, priceOracleUtxo]).compose(tx);
|
|
2848
|
+
return lucid.newTx().validTo(
|
|
2849
|
+
slotToUnixTime3(
|
|
2850
|
+
network,
|
|
2851
|
+
unixTimeToSlot2(network, Number(priceOracleDatum.expiration)) - 1
|
|
2852
|
+
)
|
|
2853
|
+
).readFrom([lrpScriptRefUtxo]).readFrom([iassetUtxo, priceOracleUtxo]).compose(tx);
|
|
2840
2854
|
}
|
|
2841
2855
|
async function adjustLrp(lucid, lrpOutRef, lovelacesAdjustAmt, lrpRefScriptOutRef, lrpParams) {
|
|
2842
2856
|
const ownAddr = await lucid.wallet().address();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@indigo-labs/indigo-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "Indigo SDK for interacting with Indigo endpoints via lucid-evolution",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
"format": "npx prettier --write src/ tests/",
|
|
14
14
|
"format:check": "npx prettier --check src/ tests/",
|
|
15
15
|
"test": "vitest run",
|
|
16
|
-
"prepare": "husky",
|
|
17
16
|
"lint-staged": "lint-staged"
|
|
18
17
|
},
|
|
19
18
|
"lint-staged": {
|
package/src/contracts/cdp.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
fromText,
|
|
9
9
|
LucidEvolution,
|
|
10
10
|
OutRef,
|
|
11
|
+
slotToUnixTime,
|
|
11
12
|
SpendingValidator,
|
|
12
13
|
TxBuilder,
|
|
13
14
|
UTxO,
|
|
@@ -41,6 +42,7 @@ import {
|
|
|
41
42
|
calculateAccruedInterest,
|
|
42
43
|
calculateUnitaryInterestSinceOracleLastUpdated,
|
|
43
44
|
} from '../helpers/interest-oracle';
|
|
45
|
+
import { oracleExpirationAwareValidity } from '../helpers/price-oracle-helpers';
|
|
44
46
|
|
|
45
47
|
export class CDPContract {
|
|
46
48
|
static async openPosition(
|
|
@@ -49,13 +51,16 @@ export class CDPContract {
|
|
|
49
51
|
mintedAmount: bigint,
|
|
50
52
|
params: SystemParams,
|
|
51
53
|
lucid: LucidEvolution,
|
|
54
|
+
currentSlot: number,
|
|
52
55
|
assetRef?: OutRef,
|
|
53
56
|
priceOracleRef?: OutRef,
|
|
54
57
|
interestOracleRef?: OutRef,
|
|
55
58
|
cdpCreatorRef?: OutRef,
|
|
56
59
|
collectorRef?: OutRef,
|
|
57
|
-
now: number = Date.now(),
|
|
58
60
|
): Promise<TxBuilder> {
|
|
61
|
+
const network = lucid.config().network;
|
|
62
|
+
const currentTime = BigInt(slotToUnixTime(network, currentSlot));
|
|
63
|
+
|
|
59
64
|
const [pkh, skh] = await addrDetails(lucid);
|
|
60
65
|
const assetOut: IAssetOutput = await (assetRef
|
|
61
66
|
? IAssetHelpers.findIAssetByRef(assetRef, lucid)
|
|
@@ -93,7 +98,7 @@ export class CDPContract {
|
|
|
93
98
|
cdpCreatorRef
|
|
94
99
|
? await lucid.utxosByOutRef([cdpCreatorRef])
|
|
95
100
|
: await lucid.utxosAtWithUnit(
|
|
96
|
-
credentialToAddress(
|
|
101
|
+
credentialToAddress(network, {
|
|
97
102
|
type: 'Script',
|
|
98
103
|
hash: params.validatorHashes.cdpCreatorHash,
|
|
99
104
|
}),
|
|
@@ -107,7 +112,7 @@ export class CDPContract {
|
|
|
107
112
|
cdpOwner: pkh.hash,
|
|
108
113
|
minted: mintedAmount,
|
|
109
114
|
collateral: collateralAmount,
|
|
110
|
-
currentTime:
|
|
115
|
+
currentTime: currentTime,
|
|
111
116
|
},
|
|
112
117
|
});
|
|
113
118
|
|
|
@@ -127,7 +132,7 @@ export class CDPContract {
|
|
|
127
132
|
cdpValue[cdpToken] = 1n;
|
|
128
133
|
const newSnapshot =
|
|
129
134
|
calculateUnitaryInterestSinceOracleLastUpdated(
|
|
130
|
-
|
|
135
|
+
currentTime,
|
|
131
136
|
interestOracleDatum,
|
|
132
137
|
) + interestOracleDatum.unitaryInterest;
|
|
133
138
|
const cdpDatum: CDPContent = {
|
|
@@ -136,7 +141,7 @@ export class CDPContract {
|
|
|
136
141
|
mintedAmt: mintedAmount,
|
|
137
142
|
cdpFees: {
|
|
138
143
|
ActiveCDPInterestTracking: {
|
|
139
|
-
lastSettled:
|
|
144
|
+
lastSettled: currentTime,
|
|
140
145
|
unitaryInterestSnapshot: newSnapshot,
|
|
141
146
|
},
|
|
142
147
|
},
|
|
@@ -163,14 +168,12 @@ export class CDPContract {
|
|
|
163
168
|
(mintedAmount * oracleDatum.price.getOnChainInt) / 1_000_000n,
|
|
164
169
|
);
|
|
165
170
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
? timeValidTo_
|
|
173
|
-
: Math.min(timeValidTo_, Number(cappedValidateTo));
|
|
171
|
+
const txValidity = oracleExpirationAwareValidity(
|
|
172
|
+
currentSlot,
|
|
173
|
+
Number(params.cdpCreatorParams.biasTime),
|
|
174
|
+
Number(oracleDatum.expiration),
|
|
175
|
+
network,
|
|
176
|
+
);
|
|
174
177
|
|
|
175
178
|
const tx = lucid
|
|
176
179
|
.newTx()
|
|
@@ -192,8 +195,8 @@ export class CDPContract {
|
|
|
192
195
|
.mintAssets(iassetTokenMintValue, Data.to(new Constr(0, [])))
|
|
193
196
|
.readFrom([iAssetTokenScriptRefUtxo])
|
|
194
197
|
.addSignerKey(pkh.hash)
|
|
195
|
-
.validFrom(
|
|
196
|
-
.validTo(
|
|
198
|
+
.validFrom(txValidity.validFrom)
|
|
199
|
+
.validTo(txValidity.validTo);
|
|
197
200
|
|
|
198
201
|
if (debtMintingFee > 0) {
|
|
199
202
|
await CollectorContract.feeTx(
|
|
@@ -212,6 +215,7 @@ export class CDPContract {
|
|
|
212
215
|
amount: bigint,
|
|
213
216
|
params: SystemParams,
|
|
214
217
|
lucid: LucidEvolution,
|
|
218
|
+
currentSlot: number,
|
|
215
219
|
assetRef?: OutRef,
|
|
216
220
|
priceOracleRef?: OutRef,
|
|
217
221
|
interestOracleRef?: OutRef,
|
|
@@ -225,6 +229,7 @@ export class CDPContract {
|
|
|
225
229
|
0n,
|
|
226
230
|
params,
|
|
227
231
|
lucid,
|
|
232
|
+
currentSlot,
|
|
228
233
|
assetRef,
|
|
229
234
|
priceOracleRef,
|
|
230
235
|
interestOracleRef,
|
|
@@ -239,6 +244,7 @@ export class CDPContract {
|
|
|
239
244
|
amount: bigint,
|
|
240
245
|
params: SystemParams,
|
|
241
246
|
lucid: LucidEvolution,
|
|
247
|
+
currentSlot: number,
|
|
242
248
|
assetRef?: OutRef,
|
|
243
249
|
priceOracleRef?: OutRef,
|
|
244
250
|
interestOracleRef?: OutRef,
|
|
@@ -252,6 +258,7 @@ export class CDPContract {
|
|
|
252
258
|
0n,
|
|
253
259
|
params,
|
|
254
260
|
lucid,
|
|
261
|
+
currentSlot,
|
|
255
262
|
assetRef,
|
|
256
263
|
priceOracleRef,
|
|
257
264
|
interestOracleRef,
|
|
@@ -266,6 +273,7 @@ export class CDPContract {
|
|
|
266
273
|
amount: bigint,
|
|
267
274
|
params: SystemParams,
|
|
268
275
|
lucid: LucidEvolution,
|
|
276
|
+
currentSlot: number,
|
|
269
277
|
assetRef?: OutRef,
|
|
270
278
|
priceOracleRef?: OutRef,
|
|
271
279
|
interestOracleRef?: OutRef,
|
|
@@ -279,6 +287,7 @@ export class CDPContract {
|
|
|
279
287
|
amount,
|
|
280
288
|
params,
|
|
281
289
|
lucid,
|
|
290
|
+
currentSlot,
|
|
282
291
|
assetRef,
|
|
283
292
|
priceOracleRef,
|
|
284
293
|
interestOracleRef,
|
|
@@ -293,6 +302,7 @@ export class CDPContract {
|
|
|
293
302
|
amount: bigint,
|
|
294
303
|
params: SystemParams,
|
|
295
304
|
lucid: LucidEvolution,
|
|
305
|
+
currentSlot: number,
|
|
296
306
|
assetRef?: OutRef,
|
|
297
307
|
priceOracleRef?: OutRef,
|
|
298
308
|
interestOracleRef?: OutRef,
|
|
@@ -306,6 +316,7 @@ export class CDPContract {
|
|
|
306
316
|
-amount,
|
|
307
317
|
params,
|
|
308
318
|
lucid,
|
|
319
|
+
currentSlot,
|
|
309
320
|
assetRef,
|
|
310
321
|
priceOracleRef,
|
|
311
322
|
interestOracleRef,
|
|
@@ -321,6 +332,7 @@ export class CDPContract {
|
|
|
321
332
|
mintAmount: bigint,
|
|
322
333
|
params: SystemParams,
|
|
323
334
|
lucid: LucidEvolution,
|
|
335
|
+
currentSlot: number,
|
|
324
336
|
assetRef?: OutRef,
|
|
325
337
|
priceOracleRef?: OutRef,
|
|
326
338
|
interestOracleRef?: OutRef,
|
|
@@ -328,9 +340,10 @@ export class CDPContract {
|
|
|
328
340
|
govRef?: OutRef,
|
|
329
341
|
treasuryRef?: OutRef,
|
|
330
342
|
): Promise<TxBuilder> {
|
|
343
|
+
const network = lucid.config().network;
|
|
331
344
|
// Find Pkh, Skh
|
|
332
345
|
const [pkh, _] = await addrDetails(lucid);
|
|
333
|
-
const
|
|
346
|
+
const currentTime = BigInt(slotToUnixTime(network, currentSlot));
|
|
334
347
|
|
|
335
348
|
// Find Outputs: iAsset Output, CDP Output, Gov Output
|
|
336
349
|
const cdp = (await lucid.utxosByOutRef([cdpRef]))[0];
|
|
@@ -372,7 +385,7 @@ export class CDPContract {
|
|
|
372
385
|
.newTx()
|
|
373
386
|
.collectFrom(
|
|
374
387
|
[cdp],
|
|
375
|
-
Data.to(new Constr(0, [
|
|
388
|
+
Data.to(new Constr(0, [currentTime, mintAmount, collateralAmount])),
|
|
376
389
|
)
|
|
377
390
|
.readFrom([iAsset.utxo, gov, cdpScriptRefUtxo])
|
|
378
391
|
.addSignerKey(pkh.hash);
|
|
@@ -384,7 +397,7 @@ export class CDPContract {
|
|
|
384
397
|
|
|
385
398
|
const newSnapshot =
|
|
386
399
|
calculateUnitaryInterestSinceOracleLastUpdated(
|
|
387
|
-
|
|
400
|
+
currentTime,
|
|
388
401
|
interestOracleDatum,
|
|
389
402
|
) + interestOracleDatum.unitaryInterest;
|
|
390
403
|
|
|
@@ -393,7 +406,7 @@ export class CDPContract {
|
|
|
393
406
|
mintedAmt: cdpD.mintedAmt + mintAmount,
|
|
394
407
|
cdpFees: {
|
|
395
408
|
ActiveCDPInterestTracking: {
|
|
396
|
-
lastSettled:
|
|
409
|
+
lastSettled: currentTime,
|
|
397
410
|
unitaryInterestSnapshot: newSnapshot,
|
|
398
411
|
},
|
|
399
412
|
},
|
|
@@ -424,19 +437,15 @@ export class CDPContract {
|
|
|
424
437
|
const od = parsePriceOracleDatum(oracleRefInput.datum);
|
|
425
438
|
if (!od) return Promise.reject(new Error('Invalid oracle input'));
|
|
426
439
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
const timeValidTo =
|
|
434
|
-
cappedValidateTo <= timeValidFrom
|
|
435
|
-
? timeValidTo_
|
|
436
|
-
: Math.min(timeValidTo_, Number(cappedValidateTo));
|
|
440
|
+
const txValidity = oracleExpirationAwareValidity(
|
|
441
|
+
currentSlot,
|
|
442
|
+
Number(params.cdpCreatorParams.biasTime),
|
|
443
|
+
Number(od.expiration),
|
|
444
|
+
network,
|
|
445
|
+
);
|
|
437
446
|
tx.readFrom([oracleRefInput])
|
|
438
|
-
.validFrom(
|
|
439
|
-
.validTo(
|
|
447
|
+
.validFrom(txValidity.validFrom)
|
|
448
|
+
.validTo(txValidity.validTo);
|
|
440
449
|
|
|
441
450
|
let fee = 0n;
|
|
442
451
|
if (collateralAmount < 0) {
|
|
@@ -456,7 +465,7 @@ export class CDPContract {
|
|
|
456
465
|
// Interest payment
|
|
457
466
|
|
|
458
467
|
const interestPaymentAsset = calculateAccruedInterest(
|
|
459
|
-
|
|
468
|
+
currentTime,
|
|
460
469
|
cdpD.cdpFees.ActiveCDPInterestTracking.unitaryInterestSnapshot,
|
|
461
470
|
cdpD.mintedAmt,
|
|
462
471
|
cdpD.cdpFees.ActiveCDPInterestTracking.lastSettled,
|
|
@@ -510,6 +519,7 @@ export class CDPContract {
|
|
|
510
519
|
cdpRef: OutRef,
|
|
511
520
|
params: SystemParams,
|
|
512
521
|
lucid: LucidEvolution,
|
|
522
|
+
currentSlot: number,
|
|
513
523
|
assetRef?: OutRef,
|
|
514
524
|
priceOracleRef?: OutRef,
|
|
515
525
|
interestOracleRef?: OutRef,
|
|
@@ -517,9 +527,10 @@ export class CDPContract {
|
|
|
517
527
|
govRef?: OutRef,
|
|
518
528
|
treasuryRef?: OutRef,
|
|
519
529
|
): Promise<TxBuilder> {
|
|
530
|
+
const network = lucid.config().network;
|
|
520
531
|
// Find Pkh, Skh
|
|
521
532
|
const [pkh, _] = await addrDetails(lucid);
|
|
522
|
-
const
|
|
533
|
+
const currentTime = BigInt(slotToUnixTime(network, currentSlot));
|
|
523
534
|
|
|
524
535
|
// Find Outputs: iAsset Output, CDP Output, Gov Output
|
|
525
536
|
const cdp = (await lucid.utxosByOutRef([cdpRef]))[0];
|
|
@@ -557,7 +568,7 @@ export class CDPContract {
|
|
|
557
568
|
|
|
558
569
|
const tx = lucid
|
|
559
570
|
.newTx()
|
|
560
|
-
.collectFrom([cdp], Data.to(new Constr(1, [
|
|
571
|
+
.collectFrom([cdp], Data.to(new Constr(1, [currentTime])))
|
|
561
572
|
.readFrom([iAsset.utxo, gov, cdpScriptRefUtxo])
|
|
562
573
|
.addSignerKey(pkh.hash);
|
|
563
574
|
if (!cdp.datum) throw new Error('Unable to find CDP Datum');
|
|
@@ -580,25 +591,21 @@ export class CDPContract {
|
|
|
580
591
|
return Promise.reject(new Error('Invalid oracle input'));
|
|
581
592
|
const od = parsePriceOracleDatum(oracleRefInput.datum);
|
|
582
593
|
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
const timeValidTo =
|
|
590
|
-
cappedValidateTo <= timeValidFrom
|
|
591
|
-
? timeValidTo_
|
|
592
|
-
: Math.min(timeValidTo_, Number(cappedValidateTo));
|
|
594
|
+
const txValidity = oracleExpirationAwareValidity(
|
|
595
|
+
currentSlot,
|
|
596
|
+
Number(params.cdpCreatorParams.biasTime),
|
|
597
|
+
Number(od.expiration),
|
|
598
|
+
network,
|
|
599
|
+
);
|
|
593
600
|
tx.readFrom([oracleRefInput])
|
|
594
|
-
.validFrom(
|
|
595
|
-
.validTo(
|
|
601
|
+
.validFrom(txValidity.validFrom)
|
|
602
|
+
.validTo(txValidity.validTo);
|
|
596
603
|
|
|
597
604
|
let fee = 0n;
|
|
598
605
|
|
|
599
606
|
// Interest payment
|
|
600
607
|
const interestPaymentAsset = calculateAccruedInterest(
|
|
601
|
-
|
|
608
|
+
currentTime,
|
|
602
609
|
cdpD.cdpFees.ActiveCDPInterestTracking.unitaryInterestSnapshot,
|
|
603
610
|
cdpD.mintedAmt,
|
|
604
611
|
cdpD.cdpFees.ActiveCDPInterestTracking.lastSettled,
|