Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions src/contracts/lrp/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ export function buildRedemptionsTx(
lovelacesForRedemption,
);

const lrpDatum = parseLrpDatumOrThrow(getInlineDatumOrThrow(lrpUtxo));
const lrpRawInlineDatum = getInlineDatumOrThrow(lrpUtxo);
const lrpDatum = parseLrpDatumOrThrow(lrpRawInlineDatum);

const resultVal = addAssets(
lrpUtxo.assets,
Expand Down Expand Up @@ -137,11 +138,14 @@ export function buildRedemptionsTx(
lrpUtxo.address,
{
kind: 'inline',
value: serialiseLrpDatum({
...lrpDatum,
lovelacesToSpend:
lrpDatum.lovelacesToSpend - lovelacesForRedemption,
}),
value: serialiseLrpDatum(
{
...lrpDatum,
lovelacesToSpend:
lrpDatum.lovelacesToSpend - lovelacesForRedemption,
},
{ _tag: 'adaptiveReplace', spentLrpDatum: lrpRawInlineDatum },
),
},
resultVal,
);
Expand Down
68 changes: 51 additions & 17 deletions src/contracts/lrp/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
OnChainDecimalSchema,
} from '../../types/on-chain-decimal';
import { option as O, function as F } from 'fp-ts';
import { match, P } from 'ts-pattern';

export const LRPParamsSchema = Data.Object({
versionRecordToken: AssetClassSchema,
Expand Down Expand Up @@ -63,27 +64,60 @@ export function parseLrpDatumOrThrow(datum: Datum): LRPDatum {
);
}

export function serialiseLrpDatum(datum: LRPDatum): Datum {
type LRPSerialisationOptions =
// No replacing, just use non-canonical format.
| { _tag: 'noReplace' }
// Adaptive replace, when the spentDatum is canonical, do the replace,
// otherwise use the non canonical.
| { _tag: 'adaptiveReplace'; spentLrpDatum: string };

export function serialiseLrpDatum(
datum: LRPDatum,
// Overall, we don't want to do the replacing. We just use non-canonical format.
serialisationOptions: LRPSerialisationOptions = { _tag: 'noReplace' },
): Datum {
const d = Data.to<LRPDatum>(datum, LRPDatum);

// If the lrp was created using a canonical on-chain decimal, we need to serialise it canonically.
// This is due to some issue related to how Aiken compares objects.
// See "Wrong continuing output" trace, specifically the spread of the previous datum ie. expecting the serialisation to be the same as it was created with
// We however do not want to do this for any lrps that are being build canonical.
const ocdSerialisedCanonical = Data.to<OnChainDecimal>(
datum.maxPrice,
OnChainDecimal,
{ canonical: true },
);
const ocdSerialisedNonCanonical = Data.to<OnChainDecimal>(
datum.maxPrice,
OnChainDecimal,
{ canonical: false },
);
return match(serialisationOptions)
.returnType<Datum>()
.with({ _tag: 'noReplace' }, () => d)
.with(
{ _tag: 'adaptiveReplace', spentLrpDatum: P.select() },
(spentLrpDatum) => {
const isSpentDatumCanonical = spentLrpDatum.includes(
Data.to<OnChainDecimal>(
parseLrpDatumOrThrow(spentLrpDatum).maxPrice,
OnChainDecimal,
{
canonical: true,
},
),
);

// When spent datum was canonical, replace.
if (isSpentDatumCanonical) {
// If the lrp was created using a canonical on-chain decimal, we need to serialise it canonically.
// This is due to some issue related to how Aiken compares objects.
// See "Wrong continuing output" trace, specifically the spread of the previous datum ie. expecting the serialisation to be the same as it was created with
// We however do not want to do this for any lrps that are being build canonical.
const ocdSerialisedCanonical = Data.to<OnChainDecimal>(
datum.maxPrice,
OnChainDecimal,
{ canonical: true },
);
const ocdSerialisedNonCanonical = Data.to<OnChainDecimal>(
datum.maxPrice,
OnChainDecimal,
{ canonical: false },
);

return d.replace(ocdSerialisedNonCanonical, ocdSerialisedCanonical);
return d.replace(ocdSerialisedNonCanonical, ocdSerialisedCanonical);
}

// return d;
return d;
},
)
.exhaustive();
}

export function serialiseLrpRedeemer(redeemer: LRPRedeemer): Redeemer {
Expand Down
1 change: 0 additions & 1 deletion src/contracts/stability-pool/types-new.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Core as EvoCore } from '@evolution-sdk/evolution';
import { match, P } from 'ts-pattern';
import { AddressSchema } from '@3rd-eye-labs/cardano-offchain-common';
import { DEFAULT_SCHEMA_OPTIONS } from '../../types/evolution-schema-options';
import { Data } from '@lucid-evolution/lucid';

export const SPIntegerSchema = EvoCore.TSchema.Struct({
value: EvoCore.TSchema.Integer,
Expand Down
1 change: 0 additions & 1 deletion src/contracts/staking/types-new.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Core as EvoCore } from '@evolution-sdk/evolution';
import { option as O, function as F } from 'fp-ts';
import { match, P } from 'ts-pattern';
import { DEFAULT_SCHEMA_OPTIONS } from '../../types/evolution-schema-options';
import { Data } from '@lucid-evolution/lucid';

const StakingPosLockedAmtSchema = EvoCore.TSchema.Map(
EvoCore.TSchema.Integer,
Expand Down
Loading