diff --git a/agora-specs/Property/MultiSig.hs b/agora-specs/Property/MultiSig.hs index f4dd60a..1e4f0bb 100644 --- a/agora-specs/Property/MultiSig.hs +++ b/agora-specs/Property/MultiSig.hs @@ -12,7 +12,6 @@ import Agora.MultiSig ( PMultiSig, pvalidatedByMultisig, ) -import Agora.Utils (tclet) import Data.Maybe (fromJust) import Data.Tagged (Tagged (Tagged)) import Data.Universe (Finite (..), Universe (..)) @@ -24,6 +23,7 @@ import Plutarch.Context.Spending ( signedWith, spendingContext, ) +import Plutarch.Extra.TermCont (pletC) import PlutusLedgerApi.V1 ( ScriptContext (scriptContextTxInfo), TxInfo (txInfoSignatories), @@ -98,8 +98,8 @@ expectedHs model = case classifyMultiSigProp model of -- | Actual implementation of @pvalidatedByMultisig@. actual :: Term s (PBuiltinPair PMultiSig PScriptContext :--> PBool) actual = plam $ \x -> unTermCont $ do - ms <- tclet $ pfstBuiltin # x - sc <- tclet $ psndBuiltin # x + ms <- pletC $ pfstBuiltin # x + sc <- pletC $ psndBuiltin # x pure $ pvalidatedByMultisig # ms # (pfield @"txInfo" # sc) -- | Proposed property. diff --git a/agora-specs/Spec/Effect/TreasuryWithdrawal.hs b/agora-specs/Spec/Effect/TreasuryWithdrawal.hs index 538dbb8..ea0f67a 100644 --- a/agora-specs/Spec/Effect/TreasuryWithdrawal.hs +++ b/agora-specs/Spec/Effect/TreasuryWithdrawal.hs @@ -155,8 +155,8 @@ specs = ] datum2 = TreasuryWithdrawalDatum - [ (head users, asset1 4 <> asset2 5) - , (users !! 1, asset1 2 <> asset2 1) + [ (head users, asset2 5 <> asset1 4) + , (users !! 1, asset2 1 <> asset1 2) , (users !! 2, asset1 1) ] [ head treasuries diff --git a/agora-specs/Spec/Utils.hs b/agora-specs/Spec/Utils.hs index fef48c4..97e1972 100644 --- a/agora-specs/Spec/Utils.hs +++ b/agora-specs/Spec/Utils.hs @@ -7,220 +7,9 @@ Tests for utility functions in 'Agora.Utils'. -} module Spec.Utils (tests) where --------------------------------------------------------------------------------- - -import Agora.Utils (phalve, pisUniq, pmergeBy, pmsort, pnubSort, pupdate) - --------------------------------------------------------------------------------- - -import Data.List (nub, sort) -import Data.Map qualified as M -import Data.Set qualified as S - --------------------------------------------------------------------------------- - -import Control.Monad.Cont (cont, runCont) import Test.Tasty (TestTree) -import Test.Tasty.QuickCheck ( - Arbitrary (arbitrary), - Property, - Testable (property), - elements, - forAll, - suchThat, - testProperty, - (.&&.), - ) -import Test.Util (updateMap) - --------------------------------------------------------------------------------- - -import PlutusTx.AssocMap qualified as AssocMap -------------------------------------------------------------------------------- tests :: [TestTree] -tests = - [ testProperty "'pmsort' sorts a list properly" prop_msortCorrect - , testProperty "'pmerge' merges two sorted lists into one sorted list" prop_mergeCorrect - , testProperty "'phalve' splits a list in half as expected" prop_halveCorrect - , testProperty "'pnubSort' sorts a list and remove duplicate elements" prop_nubSortProperly - , testProperty "'pisUniq' can tell whether all elements in a list are unique" prop_uniqueList - , testProperty "'pupdate' updates assoc maps as 'updateMap' does" prop_updateAssocMapParity - ] - --------------------------------------------------------------------------------- - --- | Yield true if 'Agora.Utils.pmsort' sorts a given list correctly. -prop_msortCorrect :: [Integer] -> Bool -prop_msortCorrect l = sorted == expected - where - -- Expected sorted list, using 'Data.List.sort'. - expected :: [Integer] - expected = sort l - - -- - - psorted :: Term _ (PBuiltinList PInteger) - psorted = pmsort # pconstant l - - sorted :: [Integer] - sorted = plift psorted - --- | Yield true if 'Agora.Utils.pmerge' merges two list into a ordered list correctly. -prop_mergeCorrect :: [Integer] -> [Integer] -> Bool -prop_mergeCorrect a b = merged == expected - where - -- Sorted list a and b - sa = sort a - sb = sort b - - -- Merge two lists which are assumed to be ordered. - merge :: [Integer] -> [Integer] -> [Integer] - merge xs [] = xs - merge [] ys = ys - merge sx@(x : xs) sy@(y : ys) - | x <= y = x : merge xs sy - | otherwise = y : merge sx ys - - expected :: [Integer] - expected = merge sa sb - - -- - - pmerged :: Term _ (PBuiltinList PInteger) - pmerged = pmergeBy # plam (#<) # pconstant sa # pconstant sb - - merged :: [Integer] - merged = plift pmerged - -{- | Yield true if Plutarch level 'Agora.Utils.phalve' splits a given list - as its Haskell level counterpart does. --} -prop_halveCorrect :: [Integer] -> Bool -prop_halveCorrect l = halved == expected - where - -- Halve a list. - halve :: [Integer] -> ([Integer], [Integer]) - halve xs = go xs xs - where - go xs [] = ([], xs) - go (x : xs) [_] = ([x], xs) - go (x : xs) (_ : _ : ys) = - let (first, last) = - go xs ys - in (x : first, last) - go [] _ = ([], []) - - expected :: ([Integer], [Integer]) - expected = halve l - - -- - - phalved :: Term _ (PPair (PBuiltinList PInteger) (PBuiltinList PInteger)) - phalved = phalve # pconstant l - - halved :: ([Integer], [Integer]) - halved = - let f = plift $ pmatch phalved $ \(PPair x _) -> x - s = plift $ pmatch phalved $ \(PPair _ x) -> x - in (f, s) - -{- | Yield true if 'Agora.Utils.pnubSort' sorts and removes - duplicate elements from a given list. --} -prop_nubSortProperly :: [Integer] -> Bool -prop_nubSortProperly l = nubbed == expected - where - -- Sort and list and then nub it. - expected :: [Integer] - expected = nub $ sort l - - -- - - pnubbed :: Term _ (PBuiltinList PInteger) - pnubbed = pnubSort # pconstant l - - nubbed :: [Integer] - nubbed = plift pnubbed - -{- | Yield true if 'Agora.Utils.isUnique' can correctly determine - whether a given list only contains unique elements or not. --} -prop_uniqueList :: [Integer] -> Bool -prop_uniqueList l = isUnique == expected - where - -- Convert input list to a set. - -- If the set's size equals to list's size, - -- the list only contains unique elements. - expected :: Bool - expected = S.size (S.fromList l) == length l - - -- - - isUnique = plift $ pisUniq # pconstant l - -{- | Test the parity between 'updateMap' and 'pupdate', - also ensure they both work correctly. --} -prop_updateAssocMapParity :: Property -prop_updateAssocMapParity = - runCont - ( do - -- Generate a bunch unique keys. - keys <- - cont $ - forAll $ - arbitrary @(S.Set Integer) `suchThat` (not . S.null) - - -- Generate key-value pairs. - kvPairs <- cont $ forAll $ mapM (\k -> (k,) <$> (arbitrary @Integer)) $ S.toList keys - - let initialMap = AssocMap.fromList kvPairs - - pinitialMap :: Term _ _ - pinitialMap = phoistAcyclic $ pconstant initialMap - - referenceMap = M.fromList kvPairs - - let pupdatedValue :: Maybe Integer -> Term _ (PMaybe PInteger) - pupdatedValue updatedValue = phoistAcyclic $ case updatedValue of - Nothing -> pcon PNothing - Just v -> pcon $ PJust $ pconstant v - - -- Given the key and the updated value, test the parity - parity key updatedValue = - let native = updateMap (const updatedValue) key initialMap - - plutarch :: AssocMap.Map Integer Integer - plutarch = - plift $ - pupdate - # plam (\_ -> pupdatedValue updatedValue) - # pconstant key - # pinitialMap - - expected = - AssocMap.fromList $ - M.toList $ - M.update (const updatedValue) key referenceMap - in expected == native - && expected == plutarch - - -- Select a key, generate a maybe value. - -- The value at the key should be set to the new value or removed. - (targetKey, _) <- cont $ forAll $ elements kvPairs - updatedValue <- cont $ forAll $ arbitrary @(Maybe Integer) - - -- Now what if the key doesn't exist in our map? - nonexistentKey <- - cont $ - forAll $ - arbitrary @Integer `suchThat` (\k -> not $ S.member k keys) - - pure - ( property (parity targetKey updatedValue) - .&&. property (parity nonexistentKey updatedValue) - ) - ) - id +tests = [] diff --git a/agora.cabal b/agora.cabal index fc6ff71..a3c6d21 100644 --- a/agora.cabal +++ b/agora.cabal @@ -98,7 +98,6 @@ common deps , generics-sop , liqwid-plutarch-extra , plutarch - , plutarch-extra , plutarch-numeric , plutarch-safe-money , plutus-core diff --git a/agora/Agora/AuthorityToken.hs b/agora/Agora/AuthorityToken.hs index bca8b3d..03e03cf 100644 --- a/agora/Agora/AuthorityToken.hs +++ b/agora/Agora/AuthorityToken.hs @@ -28,8 +28,12 @@ import Plutarch.Api.V1 ( ) import Plutarch.Api.V1.AssetClass (passetClass, passetClassValueOf) import Plutarch.Api.V1.AssocMap (PMap (PMap)) +import Plutarch.Api.V1.ScriptContext (pisTokenSpent) +import "liqwid-plutarch-extra" Plutarch.Api.V1.Value (psymbolValueOf) import "plutarch" Plutarch.Api.V1.Value (PValue (PValue)) import Plutarch.Builtin (pforgetData) +import Plutarch.Extra.List (plookup) +import Plutarch.Extra.TermCont (pguardC, pmatchC) import PlutusLedgerApi.V1.Value (AssetClass (AssetClass)) -------------------------------------------------------------------------------- @@ -38,16 +42,6 @@ import GHC.Generics qualified as GHC -------------------------------------------------------------------------------- -import Agora.Utils ( - plookup, - psymbolValueOf, - ptokenSpent, - tcassert, - tcmatch, - ) - --------------------------------------------------------------------------------- - {- | An AuthorityToken represents a proof that a particular token moved while this token was minted. In effect, this means that the validator that locked such a token must have approved @@ -74,11 +68,11 @@ newtype AuthorityToken = AuthorityToken authorityTokensValidIn :: Term s (PCurrencySymbol :--> PTxOut :--> PBool) authorityTokensValidIn = phoistAcyclic $ plam $ \authorityTokenSym txOut'' -> unTermCont $ do - PTxOut txOut' <- tcmatch txOut'' + PTxOut txOut' <- pmatchC txOut'' txOut <- tcont $ pletFields @'["address", "value"] $ txOut' - PAddress address <- tcmatch txOut.address - PValue value' <- tcmatch txOut.value - PMap value <- tcmatch value' + PAddress address <- pmatchC txOut.address + PValue value' <- pmatchC txOut.value + PMap value <- pmatchC value' pure $ pmatch (plookup # pdata authorityTokenSym # value) $ \case PJust (pfromData -> tokenMap') -> @@ -87,7 +81,7 @@ authorityTokensValidIn = phoistAcyclic $ -- GATs should only be sent to Effect validators ptraceIfFalse "authorityTokensValidIn: GAT incorrectly lives at PubKey" $ pconstant False PScriptCredential ((pfromData . (pfield @"_0" #)) -> cred) -> unTermCont $ do - PMap tokenMap <- tcmatch tokenMap' + PMap tokenMap <- pmatchC tokenMap' pure $ ptraceIfFalse "authorityTokensValidIn: GAT TokenName doesn't match ScriptHash" $ pall @@ -121,7 +115,7 @@ singleAuthorityTokenBurned gatCs txInfo mint = unTermCont $ do pall # plam ( \txInInfo' -> unTermCont $ do - PTxInInfo txInInfo <- tcmatch (pfromData txInInfo') + PTxInInfo txInInfo <- pmatchC (pfromData txInInfo') let txOut' = pfield @"resolved" # txInInfo pure $ authorityTokensValidIn # gatCs # pfromData txOut' ) @@ -134,15 +128,15 @@ authorityTokenPolicy params = plam $ \_redeemer ctx' -> pmatch ctx' $ \(PScriptContext ctx') -> unTermCont $ do ctx <- tcont $ pletFields @'["txInfo", "purpose"] ctx' - PTxInfo txInfo' <- tcmatch $ pfromData ctx.txInfo + PTxInfo txInfo' <- pmatchC $ pfromData ctx.txInfo txInfo <- tcont $ pletFields @'["inputs", "mint", "outputs"] txInfo' let inputs = txInfo.inputs mintedValue = pfromData txInfo.mint AssetClass (govCs, govTn) = params.authority govAc = passetClass # pconstant govCs # pconstant govTn - govTokenSpent = ptokenSpent # govAc # inputs + govTokenSpent = pisTokenSpent # govAc # inputs - PMinting ownSymbol' <- tcmatch $ pfromData ctx.purpose + PMinting ownSymbol' <- pmatchC $ pfromData ctx.purpose let ownSymbol = pfromData $ pfield @"_0" # ownSymbol' mintedATs = passetClassValueOf # mintedValue # (passetClass # ownSymbol # pconstant "") @@ -150,8 +144,8 @@ authorityTokenPolicy params = pif (0 #< mintedATs) ( unTermCont $ do - tcassert "Parent token did not move in minting GATs" govTokenSpent - tcassert "All outputs only emit valid GATs" $ + pguardC "Parent token did not move in minting GATs" govTokenSpent + pguardC "All outputs only emit valid GATs" $ pall # plam ( (authorityTokensValidIn # ownSymbol #) diff --git a/agora/Agora/Effect.hs b/agora/Agora/Effect.hs index 82b8730..1c35079 100644 --- a/agora/Agora/Effect.hs +++ b/agora/Agora/Effect.hs @@ -8,8 +8,8 @@ Helpers for constructing effects. module Agora.Effect (makeEffect) where import Agora.AuthorityToken (singleAuthorityTokenBurned) -import Agora.Utils (tcassert, tclet, tcmatch, tctryFrom) import Plutarch.Api.V1 (PCurrencySymbol, PScriptPurpose (PSpending), PTxInfo, PTxOutRef, PValidator, PValue) +import Plutarch.Extra.TermCont (pguardC, pletC, pmatchC, ptryFromC) import Plutarch.TryFrom () import PlutusLedgerApi.V1.Value (CurrencySymbol) @@ -30,16 +30,16 @@ makeEffect :: makeEffect gatCs' f = plam $ \datum _redeemer ctx' -> unTermCont $ do ctx <- tcont $ pletFields @'["txInfo", "purpose"] ctx' - txInfo' <- tclet ctx.txInfo + txInfo' <- pletC ctx.txInfo -- convert input datum, PData, into desierable type -- the way this conversion is performed should be defined -- by PTryFrom for each datum in effect script. - (pfromData -> datum', _) <- tctryFrom datum + (pfromData -> datum', _) <- ptryFromC datum -- ensure purpose is Spending. - PSpending txOutRef <- tcmatch $ pfromData ctx.purpose - txOutRef' <- tclet (pfield @"_0" # txOutRef) + PSpending txOutRef <- pmatchC $ pfromData ctx.purpose + txOutRef' <- pletC (pfield @"_0" # txOutRef) -- fetch minted values to ensure single GAT is burned txInfo <- tcont $ pletFields @'["mint"] txInfo' @@ -47,9 +47,9 @@ makeEffect gatCs' f = mint = txInfo.mint -- fetch script context - gatCs <- tclet $ pconstant gatCs' + gatCs <- pletC $ pconstant gatCs' - tcassert "A single authority token has been burned" $ singleAuthorityTokenBurned gatCs txInfo' mint + pguardC "A single authority token has been burned" $ singleAuthorityTokenBurned gatCs txInfo' mint -- run effect function pure $ f gatCs datum' txOutRef' txInfo' diff --git a/agora/Agora/Effect/GovernorMutation.hs b/agora/Agora/Effect/GovernorMutation.hs index 37c3a0c..caab4b3 100644 --- a/agora/Agora/Effect/GovernorMutation.hs +++ b/agora/Agora/Effect/GovernorMutation.hs @@ -31,12 +31,14 @@ import Plutarch.Api.V1 ( PValidator, PValue, ) +import Plutarch.Api.V1.ScriptContext (ptryFindDatum) import "liqwid-plutarch-extra" Plutarch.Api.V1.Value (pvalueOf) import Plutarch.DataRepr ( DerivePConstantViaData (..), PDataFields, PIsDataReprInstances (PIsDataReprInstances), ) +import Plutarch.Extra.TermCont (pguardC) import Plutarch.Lift (PConstantDecl, PLifted, PUnsafeLiftDecl) import Plutarch.TryFrom (PTryFrom (..)) import Plutarch.Unsafe (punsafeCoerce) @@ -64,8 +66,6 @@ import Agora.Utils ( isScriptAddress, mustBePDJust, mustBePJust, - ptryFindDatum, - tcassert, ) -------------------------------------------------------------------------------- @@ -145,11 +145,11 @@ mutateGovernorValidator gov = makeEffect (authorityTokenSymbolFromGovernor gov) let mint :: Term _ (PBuiltinList _) mint = pto $ pto $ pto $ pfromData txInfoF.mint - tcassert "Nothing should be minted/burnt other than GAT" $ + pguardC "Nothing should be minted/burnt other than GAT" $ plength # mint #== 1 -- Only two script inputs are alloed: one from the effect, one from the governor. - tcassert "Only self and governor script inputs are allowed" $ + pguardC "Only self and governor script inputs are allowed" $ pfoldr # phoistAcyclic ( plam $ \inInfo count -> @@ -176,11 +176,11 @@ mutateGovernorValidator gov = makeEffect (authorityTokenSymbolFromGovernor gov) govInInfo <- tcont $ pletFields @'["outRef", "resolved"] $ inputWithGST -- The effect can only modify the governor UTXO referenced in the datum. - tcassert "Can only modify the pinned governor" $ + pguardC "Can only modify the pinned governor" $ govInInfo.outRef #== datumF.governorRef -- The transaction can only have one output, which should be sent to the governor. - tcassert "Only governor output is allowed" $ + pguardC "Only governor output is allowed" $ plength # pfromData txInfoF.outputs #== 1 let govAddress = pfield @"address" #$ govInInfo.resolved @@ -188,10 +188,10 @@ mutateGovernorValidator gov = makeEffect (authorityTokenSymbolFromGovernor gov) govOutput <- tcont $ pletFields @'["address", "value", "datumHash"] govOutput' - tcassert "No output to the governor" $ + pguardC "No output to the governor" $ govOutput.address #== govAddress - tcassert "Governor output doesn't carry the GST" $ + pguardC "Governor output doesn't carry the GST" $ gstValueOf # govOutput.value #== 1 let governorOutputDatumHash = @@ -202,8 +202,8 @@ mutateGovernorValidator gov = makeEffect (authorityTokenSymbolFromGovernor gov) #$ ptryFindDatum # governorOutputDatumHash # txInfoF.datums -- Ensure the output governor datum is what we want. - tcassert "Unexpected governor datum" $ datumF.newDatum #== governorOutputDatum - tcassert "New governor datum should be valid" $ governorDatumValid # governorOutputDatum + pguardC "Unexpected governor datum" $ datumF.newDatum #== governorOutputDatum + pguardC "New governor datum should be valid" $ governorDatumValid # governorOutputDatum return $ popaque $ pconstant () where diff --git a/agora/Agora/Effect/TreasuryWithdrawal.hs b/agora/Agora/Effect/TreasuryWithdrawal.hs index 9a38790..1024e9b 100644 --- a/agora/Agora/Effect/TreasuryWithdrawal.hs +++ b/agora/Agora/Effect/TreasuryWithdrawal.hs @@ -18,7 +18,7 @@ import GHC.Generics qualified as GHC import Generics.SOP (Generic, I (I)) import Agora.Effect (makeEffect) -import Agora.Utils (findTxOutByTxOutRef, isPubKey, paddValue, tcassert, tclet, tcmatch) +import Agora.Utils (findTxOutByTxOutRef, isPubKey) import Plutarch.Api.V1 ( AmountGuarantees (Positive), KeyGuarantees (Sorted), @@ -28,14 +28,15 @@ import Plutarch.Api.V1 ( PValue, ptuple, ) -import "plutarch" Plutarch.Api.V1.Value (pnormalize) import Plutarch.Internal (punsafeCoerce) +import "plutarch" Plutarch.Api.V1.Value (pnormalize) import Plutarch.DataRepr ( DerivePConstantViaData (..), PDataFields, PIsDataReprInstances (..), ) +import Plutarch.Extra.TermCont (pguardC, pletC, pmatchC) import Plutarch.Lift (PConstantDecl, PUnsafeLiftDecl (..)) import Plutarch.TryFrom (PTryFrom (..)) import PlutusLedgerApi.V1.Credential (Credential) @@ -111,10 +112,10 @@ treasuryWithdrawalValidator currSymbol = makeEffect currSymbol $ \_cs (datum' :: Term _ PTreasuryWithdrawalDatum) txOutRef' txInfo' -> unTermCont $ do datum <- tcont $ pletFields @'["receivers", "treasuries"] datum' txInfo <- tcont $ pletFields @'["outputs", "inputs"] txInfo' - PJust txOut <- tcmatch $ findTxOutByTxOutRef # txOutRef' # pfromData txInfo.inputs + PJust txOut <- pmatchC $ findTxOutByTxOutRef # txOutRef' # pfromData txInfo.inputs effInput <- tcont $ pletFields @'["address", "value"] $ txOut outputValues <- - tclet $ + pletC $ pmap # plam ( \(pfromData -> txOut') -> unTermCont $ do @@ -124,7 +125,7 @@ treasuryWithdrawalValidator currSymbol = makeEffect currSymbol $ ) # txInfo.outputs inputValues <- - tclet $ + pletC $ pmap # plam ( \((pfield @"resolved" #) . pfromData -> txOut') -> unTermCont $ do @@ -136,10 +137,13 @@ treasuryWithdrawalValidator currSymbol = makeEffect currSymbol $ let ofTreasury = pfilter # plam (\((pfield @"_0" #) . pfromData -> cred) -> pelem # cred # datum.treasuries) - sumValues = - pfoldr - # plam (\((pfield @"_1" #) . pfromData -> x) ((pnormalize #) -> y) -> paddValue # pfromData x # y) - # punsafeCoerce (pconstant (mempty :: Value)) + sumValues = phoistAcyclic $ + plam $ \v -> + pnormalize + #$ pfoldr + # plam (\(pfromData . (pfield @"_1" #) -> x) y -> x <> y) + # mempty + # v treasuryInputValuesSum = sumValues #$ ofTreasury # inputValues treasuryOutputValuesSum = sumValues #$ ofTreasury # outputValues receiverValuesSum = sumValues # datum.receivers @@ -148,7 +152,7 @@ treasuryWithdrawalValidator currSymbol = makeEffect currSymbol $ pall # plam (\out -> pelem # out # outputValues) #$ datum.receivers excessShouldBePaidToInputs = - pdata (paddValue # receiverValuesSum # treasuryOutputValuesSum) #== pdata treasuryInputValuesSum + treasuryOutputValuesSum <> receiverValuesSum #== treasuryInputValuesSum shouldNotPayToEffect = pnot #$ pany # plam @@ -166,8 +170,8 @@ treasuryWithdrawalValidator currSymbol = makeEffect currSymbol $ ) # inputValues - tcassert "Transaction should not pay to effects" shouldNotPayToEffect - tcassert "Transaction output does not match receivers" outputContentMatchesRecivers - tcassert "Remainders should be returned to the treasury" excessShouldBePaidToInputs - tcassert "Transaction should only have treasuries specified in the datum as input" inputsAreOnlyTreasuriesOrCollateral + pguardC "Transaction should not pay to effects" shouldNotPayToEffect + pguardC "Transaction output does not match receivers" outputContentMatchesRecivers + pguardC "Remainders should be returned to the treasury" excessShouldBePaidToInputs + pguardC "Transaction should only have treasuries specified in the datum as input" inputsAreOnlyTreasuriesOrCollateral pure . popaque $ pconstant () diff --git a/agora/Agora/Governor.hs b/agora/Agora/Governor.hs index 7afcb52..3fd2a5a 100644 --- a/agora/Agora/Governor.hs +++ b/agora/Agora/Governor.hs @@ -26,6 +26,7 @@ module Agora.Governor ( -------------------------------------------------------------------------------- import Control.Applicative (Const) +import Data.Tagged (Tagged (..)) import GHC.Generics qualified as GHC import Generics.SOP (Generic, I (I)) @@ -44,18 +45,16 @@ import Agora.Proposal.Time ( ProposalTimingConfig, ) import Agora.SafeMoney (GTTag) -import Agora.Utils (tclet) -------------------------------------------------------------------------------- -import Data.Tagged (Tagged (..)) import Plutarch.DataRepr ( DerivePConstantViaData (..), PDataFields, PIsDataReprInstances (PIsDataReprInstances), ) import Plutarch.Extra.Comonad (pextract) -import Plutarch.Extra.TermCont (pmatchC) +import Plutarch.Extra.TermCont (pletC, pmatchC) import Plutarch.Lift (PConstantDecl, PUnsafeLiftDecl (..)) import Plutarch.SafeMoney (PDiscrete (..)) import Plutarch.TryFrom (PTryFrom (..)) @@ -196,9 +195,9 @@ governorDatumValid = phoistAcyclic $ PDiscrete draft' <- pmatchC thresholds.create PDiscrete vote' <- pmatchC thresholds.vote - execute <- tclet $ pextract # execute' - draft <- tclet $ pextract # draft' - vote <- tclet $ pextract # vote' + execute <- pletC $ pextract # execute' + draft <- pletC $ pextract # draft' + vote <- pletC $ pextract # vote' pure $ foldr1 diff --git a/agora/Agora/Governor/Scripts.hs b/agora/Agora/Governor/Scripts.hs index 8901761..b832c86 100644 --- a/agora/Agora/Governor/Scripts.hs +++ b/agora/Agora/Governor/Scripts.hs @@ -77,17 +77,7 @@ import Agora.Utils ( mustBePDJust, mustBePJust, mustFindDatum', - pfindTxInByTxOutRef, - pisDJust, - pisUTXOSpent, - psymbolValueOf, - ptryFindDatum, - ptxSignedBy, - pvalueSpent, scriptHashFromAddress, - tcassert, - tclet, - tcmatch, validatorHashToAddress, validatorHashToTokenName, ) @@ -125,6 +115,10 @@ import Plutarch.TryFrom () -------------------------------------------------------------------------------- +import Plutarch.Api.V1.ScriptContext (pfindTxInByTxOutRef, pisUTXOSpent, ptryFindDatum, ptxSignedBy, pvalueSpent) +import "liqwid-plutarch-extra" Plutarch.Api.V1.Value (psymbolValueOf) +import Plutarch.Extra.Maybe (pisDJust) +import Plutarch.Extra.TermCont import PlutusLedgerApi.V1 ( CurrencySymbol (..), MintingPolicy, @@ -166,21 +160,21 @@ governorPolicy gov = plam $ \_ ctx' -> unTermCont $ do let oref = pconstant gov.gstOutRef - PMinting ((pfield @"_0" #) -> ownSymbol) <- tcmatch (pfromData $ pfield @"purpose" # ctx') + PMinting ((pfield @"_0" #) -> ownSymbol) <- pmatchC (pfromData $ pfield @"purpose" # ctx') let ownAssetClass = passetClass # ownSymbol # pconstant "" txInfo = pfromData $ pfield @"txInfo" # ctx' txInfoF <- tcont $ pletFields @'["mint", "inputs", "outputs", "datums", "validRange"] txInfo - tcassert "Referenced utxo should be spent" $ + pguardC "Referenced utxo should be spent" $ pisUTXOSpent # oref # txInfoF.inputs - tcassert "Exactly one token should be minted" $ + pguardC "Exactly one token should be minted" $ psymbolValueOf # ownSymbol # txInfoF.mint #== 1 #&& passetClassValueOf # txInfoF.mint # ownAssetClass #== 1 govOutput <- - tclet $ + pletC $ mustBePJust # "Governor output not found" #$ pfind @@ -285,13 +279,13 @@ governorValidator gov = (pfromData -> redeemer, _) <- tcont $ ptryFrom redeemer' ctxF <- tcont $ pletFields @'["txInfo", "purpose"] ctx' - txInfo' <- tclet $ pfromData $ ctxF.txInfo + txInfo' <- pletC $ pfromData $ ctxF.txInfo txInfoF <- tcont $ pletFields @'["mint", "inputs", "outputs", "datums", "signatories", "validRange"] txInfo' - PSpending (pfromData . (pfield @"_0" #) -> ownInputRef) <- tcmatch $ pfromData ctxF.purpose + PSpending (pfromData . (pfield @"_0" #) -> ownInputRef) <- pmatchC $ pfromData ctxF.purpose ((pfield @"resolved" #) -> ownInput) <- - tclet $ + pletC $ mustBePJust # "Own input not found" #$ pfindTxInByTxOutRef # ownInputRef # txInfoF.inputs ownInputF <- tcont $ pletFields @'["address", "value"] ownInput @@ -310,27 +304,27 @@ governorValidator gov = -- Check that GST will be returned to the governor. let ownInputGSTAmount = psymbolValueOf # pgstSymbol # ownInputF.value - tcassert "Own input should have exactly one state token" $ + pguardC "Own input should have exactly one state token" $ ownInputGSTAmount #== 1 - ownOutputs <- tclet $ findOutputsToAddress # txInfoF.outputs # ownAddress - tcassert "Exactly one utxo should be sent to the governor" $ + ownOutputs <- pletC $ findOutputsToAddress # txInfoF.outputs # ownAddress + pguardC "Exactly one utxo should be sent to the governor" $ plength # ownOutputs #== 1 ownOutput <- tcont $ pletFields @'["value", "datumHash"] $ phead # ownOutputs let ownOuputGSTAmount = psymbolValueOf # pgstSymbol # ownOutput.value - tcassert "State token should stay at governor's address" $ + pguardC "State token should stay at governor's address" $ ownOuputGSTAmount #== 1 -- Check that own output have datum of type 'GovernorDatum'. let outputGovernorStateDatumHash = mustBePDJust # "Governor output doesn't have datum" # ownOutput.datumHash newGovernorDatum <- - tclet $ + pletC $ pfromData $ mustBePJust # "Ouput governor state datum not found" #$ ptryFindDatum # outputGovernorStateDatumHash # txInfoF.datums - tcassert "New datum is not valid" $ governorDatumValid # newGovernorDatum + pguardC "New datum is not valid" $ governorDatumValid # newGovernorDatum pure $ pmatch redeemer $ \case @@ -347,19 +341,19 @@ governorValidator gov = .& #createProposalTimeRangeMaxWidth .= oldGovernorDatumF.createProposalTimeRangeMaxWidth ) - tcassert "Unexpected governor state datum" $ + pguardC "Unexpected governor state datum" $ newGovernorDatum #== expectedNewDatum -- Check that exactly one proposal token is being minted. - tcassert "Exactly one proposal token must be minted" $ + pguardC "Exactly one proposal token must be minted" $ hasOnlyOneTokenOfCurrencySymbol # ppstSymbol # txInfoF.mint -- Check that a stake is spent to create the propsal, -- and the value it contains meets the requirement. stakeInput <- - tclet $ + pletC $ mustBePJust # "Stake input not found" #$ pfind # phoistAcyclic ( plam $ @@ -374,7 +368,7 @@ governorValidator gov = stakeInputF <- tcont $ pletFields @'["datumHash", "value"] $ pfield @"resolved" # stakeInput - tcassert "Stake input doesn't have datum" $ + pguardC "Stake input doesn't have datum" $ pisDJust # stakeInputF.datumHash let stakeInputDatum = mustFindDatum' @PStakeDatum # stakeInputF.datumHash # txInfoF.datums @@ -382,18 +376,18 @@ governorValidator gov = stakeInputDatumF <- tcont $ pletFields @["stakedAmount", "owner", "lockedBy"] stakeInputDatum - tcassert "Required amount of stake GTs should be presented" $ + pguardC "Required amount of stake GTs should be presented" $ stakeInputDatumF.stakedAmount #== (pgtValueOf # stakeInputF.value) -- TODO: Is this required? - tcassert "Tx should be signed by the stake owner" $ + pguardC "Tx should be signed by the stake owner" $ ptxSignedBy # txInfoF.signatories # stakeInputDatumF.owner -- Check that the newly minted PST is sent to the proposal validator, -- and the datum it carries is legal. outputsToProposalValidatorWithStateToken <- - tclet $ + pletC $ pfilter # phoistAcyclic ( plam $ @@ -406,18 +400,18 @@ governorValidator gov = ) # pfromData txInfoF.outputs - tcassert "Exactly one UTXO with proposal state token should be sent to the proposal validator" $ + pguardC "Exactly one UTXO with proposal state token should be sent to the proposal validator" $ plength # outputsToProposalValidatorWithStateToken #== 1 - outputDatumHash <- tclet $ pfield @"datumHash" #$ phead # outputsToProposalValidatorWithStateToken + outputDatumHash <- pletC $ pfield @"datumHash" #$ phead # outputsToProposalValidatorWithStateToken proposalOutputDatum' <- - tclet $ + pletC $ mustFindDatum' @PProposalDatum # outputDatumHash # txInfoF.datums - tcassert "Proposal datum must be valid" $ + pguardC "Proposal datum must be valid" $ proposalDatumValid' # proposalOutputDatum' proposalOutputDatum <- @@ -426,7 +420,7 @@ governorValidator gov = @'["effects", "cosigners", "proposalId", "votes"] proposalOutputDatum' - tcassert "Proposal should have only one cosigner" $ + pguardC "Proposal should have only one cosigner" $ plength # pfromData proposalOutputDatum.cosigners #== 1 let -- Votes should be empty at this point @@ -449,17 +443,17 @@ governorValidator gov = .& #startingTime .= pdata expectedStartingTime ) - tcassert "Datum correct" $ expectedProposalOut #== proposalOutputDatum' + pguardC "Datum correct" $ expectedProposalOut #== proposalOutputDatum' let cosigner = phead # pfromData proposalOutputDatum.cosigners - tcassert "Cosigner should be the stake owner" $ + pguardC "Cosigner should be the stake owner" $ pdata stakeInputDatumF.owner #== cosigner -- Check the output stake has been proposly updated. stakeOutput <- - tclet $ + pletC $ mustBePJust # "Stake output not found" #$ pfind @@ -476,7 +470,7 @@ governorValidator gov = stakeOutputF <- tcont $ pletFields @'["datumHash", "value"] $ stakeOutput - tcassert "Staked GTs should be sent back to stake validator" $ + pguardC "Staked GTs should be sent back to stake validator" $ stakeInputDatumF.stakedAmount #== (pgtValueOf # stakeOutputF.value) let stakeOutputDatumHash = mustBePDJust # "Stake output should have datum" # stakeOutputF.datumHash @@ -514,18 +508,18 @@ governorValidator gov = .& #lockedBy .= pdata expectedProposalLocks ) - tcassert "Unexpected stake output datum" $ expectedStakeOutputDatum #== stakeOutputDatum + pguardC "Unexpected stake output datum" $ expectedStakeOutputDatum #== stakeOutputDatum pure $ popaque $ pconstant () -------------------------------------------------------------------------- PMintGATs _ -> unTermCont $ do - tcassert "Governor state should not be changed" $ newGovernorDatum #== oldGovernorDatum + pguardC "Governor state should not be changed" $ newGovernorDatum #== oldGovernorDatum -- Filter out proposal inputs and ouputs using PST and the address of proposal validator. - tcassert "The governor can only process one proposal at a time" $ + pguardC "The governor can only process one proposal at a time" $ (psymbolValueOf # ppstSymbol #$ pvalueSpent # txInfoF.inputs) #== 1 proposalInputF <- @@ -561,17 +555,17 @@ governorValidator gov = # pfromData txInfoF.outputs proposalInputDatum <- - tclet $ + pletC $ mustFindDatum' @PProposalDatum # proposalInputF.datumHash # txInfoF.datums proposalOutputDatum <- - tclet $ + pletC $ mustFindDatum' @PProposalDatum # proposalOutputF.datumHash # txInfoF.datums - tcassert "Proposal datum must be valid" $ + pguardC "Proposal datum must be valid" $ proposalDatumValid' # proposalInputDatum #&& proposalDatumValid' # proposalOutputDatum @@ -582,7 +576,7 @@ governorValidator gov = -- Check that the proposal state is advanced so that a proposal cannot be executed twice. - tcassert "Proposal must be in locked(executable) state in order to execute effects" $ + pguardC "Proposal must be in locked(executable) state in order to execute effects" $ proposalInputDatumF.status #== pconstantData Locked let expectedOutputProposalDatum = @@ -598,7 +592,7 @@ governorValidator gov = .& #startingTime .= proposalInputDatumF.startingTime ) - tcassert "Unexpected output proposal datum" $ + pguardC "Unexpected output proposal datum" $ pdata proposalOutputDatum #== pdata expectedOutputProposalDatum -- TODO: anything else to check here? @@ -609,16 +603,16 @@ governorValidator gov = finalResultTag = pwinner # proposalInputDatumF.votes # quorum # neutralOption -- The effects of the winner outcome. - effectGroup <- tclet $ plookup' # finalResultTag #$ proposalInputDatumF.effects + effectGroup <- pletC $ plookup' # finalResultTag #$ proposalInputDatumF.effects - gatCount <- tclet $ plength #$ pto $ pto effectGroup + gatCount <- pletC $ plength #$ pto $ pto effectGroup - tcassert "Required amount of GATs should be minted" $ + pguardC "Required amount of GATs should be minted" $ psymbolValueOf # patSymbol # txInfoF.mint #== gatCount -- Ensure that every GAT goes to one of the effects in the winner effect group. outputsWithGAT <- - tclet $ + pletC $ pfilter # phoistAcyclic ( plam @@ -628,7 +622,7 @@ governorValidator gov = ) # pfromData txInfoF.outputs - tcassert "Output GATs is more than minted GATs" $ + pguardC "Output GATs is more than minted GATs" $ plength # outputsWithGAT #== gatCount let gatOutputValidator' :: Term s (PMap _ PValidatorHash PDatumHash :--> PAsData PTxOut :--> PBool) diff --git a/agora/Agora/Proposal.hs b/agora/Agora/Proposal.hs index 00fb0ce..9202bcc 100644 --- a/agora/Agora/Proposal.hs +++ b/agora/Agora/Proposal.hs @@ -35,8 +35,23 @@ module Agora.Proposal ( pneutralOption, ) where +-------------------------------------------------------------------------------- + +import Control.Applicative (Const) +import Control.Arrow (first) +import Data.Tagged (Tagged) import GHC.Generics qualified as GHC import Generics.SOP (Generic, I (I)) + +-------------------------------------------------------------------------------- + +import PlutusLedgerApi.V1 (DatumHash, PubKeyHash, ValidatorHash) +import PlutusLedgerApi.V1.Value (AssetClass) +import PlutusTx qualified +import PlutusTx.AssocMap qualified as AssocMap + +-------------------------------------------------------------------------------- + import Plutarch.Api.V1 ( KeyGuarantees (Unsorted), PDatumHash, @@ -44,18 +59,11 @@ import Plutarch.Api.V1 ( PPubKeyHash, PValidatorHash, ) -import PlutusTx qualified -import PlutusTx.AssocMap qualified as AssocMap - --------------------------------------------------------------------------------- - -import Agora.Proposal.Time (PProposalStartingTime, PProposalTimingConfig, ProposalStartingTime, ProposalTimingConfig) -import Agora.SafeMoney (GTTag) -import Agora.Utils (mustBePJust, pkeysEqual, pmapMap, pnotNull, tclet) -import Control.Applicative (Const) -import Control.Arrow (first) -import Data.Tagged (Tagged) import Plutarch.DataRepr (DerivePConstantViaData (..), PDataFields, PIsDataReprInstances (..)) +import Plutarch.Extra.List (pnotNull) +import Plutarch.Extra.Map qualified as PM +import Plutarch.Extra.Map.Unsorted qualified as PUM +import Plutarch.Extra.TermCont (pletC) import Plutarch.Lift ( DerivePConstantViaNewtype (..), PConstantDecl, @@ -64,8 +72,12 @@ import Plutarch.Lift ( import Plutarch.SafeMoney (PDiscrete) import Plutarch.TryFrom (PTryFrom (PTryFromExcess, ptryFrom')) import Plutarch.Unsafe (punsafeCoerce) -import PlutusLedgerApi.V1 (DatumHash, PubKeyHash, ValidatorHash) -import PlutusLedgerApi.V1.Value (AssetClass) + +-------------------------------------------------------------------------------- + +import Agora.Proposal.Time (PProposalStartingTime, PProposalTimingConfig, ProposalStartingTime, ProposalTimingConfig) +import Agora.SafeMoney (GTTag) +import Agora.Utils (mustBePJust) -------------------------------------------------------------------------------- -- Haskell-land @@ -278,6 +290,10 @@ instance PTryFrom PData (PAsData PResultTag) where type PTryFromExcess PData (PAsData PResultTag) = PTryFromExcess PData (PAsData PInteger) ptryFrom' d k = ptryFrom' @_ @(PAsData PInteger) d $ + -- JUSTIFICATION: + -- We are coercing from @PAsData PInteger@ to @PAsData PResultTag@. + -- Since 'PResultTag' is a simple newtype, their shape is the same. + -- JUSTIFICATION: -- We are coercing from @PAsData PInteger@ to @PAsData PResultTag@. -- Since 'PResultTag' is a simple newtype, their shape is the same. @@ -291,6 +307,10 @@ instance PTryFrom PData (PAsData PProposalId) where type PTryFromExcess PData (PAsData PProposalId) = PTryFromExcess PData (PAsData PInteger) ptryFrom' d k = ptryFrom' @_ @(PAsData PInteger) d $ + -- JUSTIFICATION: + -- We are coercing from @PAsData PInteger@ to @PAsData PProposalId@. + -- Since 'PProposalId' is a simple newtype, their shape is the same. + -- JUSTIFICATION: -- We are coercing from @PAsData PInteger@ to @PAsData PProposalId@. -- Since 'PProposalId' is a simple newtype, their shape is the same. @@ -360,7 +380,7 @@ pemptyVotesFor = plam ( \m -> pcon $ - PProposalVotes $ pmapMap # plam (const $ pconstant 0) # m + PProposalVotes $ PM.pmap # plam (const $ pconstant 0) # m ) -- | Plutarch-level version of 'ProposalDatum'. @@ -448,8 +468,8 @@ proposalDatumValid proposal = (#&&) [ ptraceIfFalse "Proposal has at least one ResultTag has no effects" atLeastOneNegativeResult , ptraceIfFalse "Proposal has at least one cosigner" $ pnotNull # pfromData datum.cosigners - , ptraceIfFalse "Proposal has fewer cosigners than the limit" $ plength # (pfromData datum.cosigners) #<= pconstant proposal.maximumCosigners - , ptraceIfFalse "Proposal votes and effects are compatible with each other" $ pkeysEqual # datum.effects # pto (pfromData datum.votes) + , ptraceIfFalse "Proposal has fewer cosigners than the limit" $ plength # pfromData datum.cosigners #<= pconstant proposal.maximumCosigners + , ptraceIfFalse "Proposal votes and effects are compatible with each other" $ PUM.pkeysEqual # datum.effects # pto (pfromData datum.votes) ] {- | Find the winner result tag, given the votes, the quorum the "neutral" result tag. @@ -467,9 +487,9 @@ pwinner :: ) pwinner = phoistAcyclic $ plam $ \votes quorum neutral -> unTermCont $ do - winner <- tclet $ phighestVotes # votes - winnerResultTag <- tclet $ pfromData $ pfstBuiltin # winner - highestVotes <- tclet $ pfromData $ psndBuiltin # winner + winner <- pletC $ phighestVotes # votes + winnerResultTag <- pletC $ pfromData $ pfstBuiltin # winner + highestVotes <- pletC $ pfromData $ psndBuiltin # winner let l :: Term _ (PBuiltinList _) l = pto $ pto votes diff --git a/agora/Agora/Proposal/Scripts.hs b/agora/Agora/Proposal/Scripts.hs index a13584a..f35e95f 100644 --- a/agora/Agora/Proposal/Scripts.hs +++ b/agora/Agora/Proposal/Scripts.hs @@ -31,17 +31,6 @@ import Agora.Utils ( getMintingPolicySymbol, mustBePJust, mustFindDatum', - pisJust, - pisUniqBy, - psymbolValueOf, - ptokenSpent, - ptxSignedBy, - pupdate, - pvalueSpent, - tcassert, - tclet, - tcmatch, - tctryFrom, ) import Plutarch.Api.V1 ( PMintingPolicy, @@ -51,10 +40,23 @@ import Plutarch.Api.V1 ( PValidator, ) import Plutarch.Api.V1.AssetClass (passetClass, passetClassValueOf) +import Plutarch.Api.V1.ScriptContext ( + pisTokenSpent, + ptxSignedBy, + pvalueSpent, + ) +import "liqwid-plutarch-extra" Plutarch.Api.V1.Value (psymbolValueOf) import Plutarch.Extra.Comonad (pextract) -import Plutarch.Extra.Map (plookup) +import Plutarch.Extra.List (pisUniqBy) +import Plutarch.Extra.Map (plookup, pupdate) +import Plutarch.Extra.Maybe (pisJust) import Plutarch.Extra.Record (mkRecordConstr, (.&), (.=)) -import Plutarch.Extra.TermCont (pmatchC) +import Plutarch.Extra.TermCont ( + pguardC, + pletC, + pmatchC, + ptryFromC, + ) import Plutarch.SafeMoney (PDiscrete (..)) import PlutusLedgerApi.V1.Value (AssetClass (AssetClass)) @@ -82,27 +84,27 @@ proposalPolicy :: ClosedTerm PMintingPolicy proposalPolicy (AssetClass (govCs, govTn)) = plam $ \_redeemer ctx' -> unTermCont $ do - PScriptContext ctx' <- tcmatch ctx' + PScriptContext ctx' <- pmatchC ctx' ctx <- tcont $ pletFields @'["txInfo", "purpose"] ctx' - PTxInfo txInfo' <- tcmatch $ pfromData ctx.txInfo + PTxInfo txInfo' <- pmatchC $ pfromData ctx.txInfo txInfo <- tcont $ pletFields @'["inputs", "mint"] txInfo' - PMinting _ownSymbol <- tcmatch $ pfromData ctx.purpose + PMinting _ownSymbol <- pmatchC $ pfromData ctx.purpose let inputs = txInfo.inputs mintedValue = pfromData txInfo.mint - PMinting ownSymbol' <- tcmatch $ pfromData ctx.purpose + PMinting ownSymbol' <- pmatchC $ pfromData ctx.purpose let mintedProposalST = passetClassValueOf # mintedValue # (passetClass # (pfield @"_0" # ownSymbol') # pconstant "") - tcassert "Governance state-thread token must move" $ - ptokenSpent + pguardC "Governance state-thread token must move" $ + pisTokenSpent # (passetClass # pconstant govCs # pconstant govTn) # inputs - tcassert "Minted exactly one proposal ST" $ + pguardC "Minted exactly one proposal ST" $ mintedProposalST #== 1 pure $ popaque (pconstant ()) @@ -136,10 +138,10 @@ A list of all time-sensitive redeemers and their requirements: proposalValidator :: Proposal -> ClosedTerm PValidator proposalValidator proposal = plam $ \datum redeemer ctx' -> unTermCont $ do - PScriptContext ctx' <- tcmatch ctx' + PScriptContext ctx' <- pmatchC ctx' ctx <- tcont $ pletFields @'["txInfo", "purpose"] ctx' - txInfo <- tclet $ pfromData ctx.txInfo - PTxInfo txInfo' <- tcmatch txInfo + txInfo <- pletC $ pfromData ctx.txInfo + PTxInfo txInfo' <- pmatchC txInfo txInfoF <- tcont $ pletFields @@ -151,15 +153,15 @@ proposalValidator proposal = , "validRange" ] txInfo' - PSpending ((pfield @"_0" #) -> txOutRef) <- tcmatch $ pfromData ctx.purpose + PSpending ((pfield @"_0" #) -> txOutRef) <- pmatchC $ pfromData ctx.purpose - PJust txOut <- tcmatch $ findTxOutByTxOutRef # txOutRef # txInfoF.inputs + PJust txOut <- pmatchC $ findTxOutByTxOutRef # txOutRef # txInfoF.inputs txOutF <- tcont $ pletFields @'["address", "value"] $ txOut (pfromData -> proposalDatum, _) <- - tctryFrom @(PAsData PProposalDatum) datum + ptryFromC @(PAsData PProposalDatum) datum (pfromData -> proposalRedeemer, _) <- - tctryFrom @(PAsData PProposalRedeemer) redeemer + ptryFromC @(PAsData PProposalRedeemer) redeemer proposalF <- tcont $ @@ -175,29 +177,29 @@ proposalValidator proposal = ] proposalDatum - ownAddress <- tclet $ txOutF.address + ownAddress <- pletC $ txOutF.address let stCurrencySymbol = pconstant $ getMintingPolicySymbol (proposalPolicy proposal.governorSTAssetClass) - valueSpent <- tclet $ pvalueSpent # txInfoF.inputs - spentST <- tclet $ psymbolValueOf # stCurrencySymbol #$ valueSpent + valueSpent <- pletC $ pvalueSpent # txInfoF.inputs + spentST <- pletC $ psymbolValueOf # stCurrencySymbol #$ valueSpent let AssetClass (stakeSym, stakeTn) = proposal.stakeSTAssetClass stakeSTAssetClass <- - tclet $ passetClass # pconstant stakeSym # pconstant stakeTn + pletC $ passetClass # pconstant stakeSym # pconstant stakeTn spentStakeST <- - tclet $ passetClassValueOf # valueSpent # stakeSTAssetClass + pletC $ passetClassValueOf # valueSpent # stakeSTAssetClass - signedBy <- tclet $ ptxSignedBy # txInfoF.signatories + signedBy <- pletC $ ptxSignedBy # txInfoF.signatories - tcassert "ST at inputs must be 1" (spentST #== 1) + pguardC "ST at inputs must be 1" (spentST #== 1) - currentTime <- tclet $ currentProposalTime # txInfoF.validRange + currentTime <- pletC $ currentProposalTime # txInfoF.validRange -- Filter out own output with own address and PST. -- Delay the evaluation cause in some cases there won't be any continuing output. ownOutput <- - tclet $ + pletC $ mustBePJust # "Own output should be present" #$ pfind # plam ( \input -> unTermCont $ do @@ -209,7 +211,7 @@ proposalValidator proposal = # pfromData txInfoF.outputs proposalOut <- - tclet $ + pletC $ mustFindDatum' @PProposalDatum # (pfield @"datumHash" # ownOutput) # txInfoF.datums @@ -217,17 +219,17 @@ proposalValidator proposal = pure $ pmatch proposalRedeemer $ \case PVote r -> unTermCont $ do - tcassert "Input proposal must be in VotingReady state" $ + pguardC "Input proposal must be in VotingReady state" $ proposalF.status #== pconstant VotingReady - tcassert "Proposal time should be wthin the voting period" $ + pguardC "Proposal time should be wthin the voting period" $ isVotingPeriod # proposalF.timingConfig # proposalF.startingTime # currentTime -- Ensure the transaction is voting to a valid 'ResultTag'(outcome). - PProposalVotes voteMap <- tcmatch proposalF.votes - voteFor <- tclet $ pfromData $ pfield @"resultTag" # r + PProposalVotes voteMap <- pmatchC proposalF.votes + voteFor <- pletC $ pfromData $ pfield @"resultTag" # r - tcassert "Vote option should be valid" $ + pguardC "Vote option should be valid" $ pisJust #$ plookup # voteFor # voteMap -- Find the input stake, the amount of new votes should be the 'stakedAmount'. @@ -248,7 +250,7 @@ proposalValidator proposal = stakeInF <- tcont $ pletFields @'["stakedAmount", "lockedBy", "owner"] stakeIn -- Ensure that no lock with the current proposal id has been put on the stake. - tcassert "Same stake shouldn't vote on the same propsoal twice" $ + pguardC "Same stake shouldn't vote on the same propsoal twice" $ pnot #$ pany # plam ( \((pfield @"proposalTag" #) . pfromData -> pid) -> @@ -281,7 +283,7 @@ proposalValidator proposal = .& #startingTime .= proposalF.startingTime ) - tcassert "Output proposal should be valid" $ proposalOut #== expectedProposalOut + pguardC "Output proposal should be valid" $ proposalOut #== expectedProposalOut -- We validate the output stake datum here as well: We need the vote option -- to create a valid 'ProposalLock', however the vote option is encoded @@ -318,26 +320,26 @@ proposalValidator proposal = .& #lockedBy .= pdata expectedProposalLocks ) - tcassert "Output stake should be locked by the proposal" $ expectedStakeOut #== stakeOut + pguardC "Output stake should be locked by the proposal" $ expectedStakeOut #== stakeOut pure $ popaque (pconstant ()) -------------------------------------------------------------------------- PCosign r -> unTermCont $ do - newSigs <- tclet $ pfield @"newCosigners" # r + newSigs <- pletC $ pfield @"newCosigners" # r - tcassert "Cosigners are unique" $ + pguardC "Cosigners are unique" $ pisUniqBy # phoistAcyclic (plam (#==)) # phoistAcyclic (plam $ \(pfromData -> x) (pfromData -> y) -> x #< y) # newSigs - tcassert "Signed by all new cosigners" $ + pguardC "Signed by all new cosigners" $ pall # signedBy # newSigs - tcassert "As many new cosigners as Stake datums" $ + pguardC "As many new cosigners as Stake datums" $ spentStakeST #== plength # newSigs - tcassert "All new cosigners are witnessed by their Stake datums" $ + pguardC "All new cosigners are witnessed by their Stake datums" $ pall # plam ( \sig -> @@ -367,7 +369,7 @@ proposalValidator proposal = .& #startingTime .= proposalF.startingTime ) - tcassert "Signatures are correctly added to cosignature list" $ + pguardC "Signatures are correctly added to cosignature list" $ proposalOut #== expectedDatum pure $ popaque (pconstant ()) @@ -376,10 +378,10 @@ proposalValidator proposal = popaque (pconstant ()) -------------------------------------------------------------------------- PAdvanceProposal _r -> unTermCont $ do - tcassert "No stake input is allowed" $ spentStakeST #== 0 + pguardC "No stake input is allowed" $ spentStakeST #== 0 - currentTime <- tclet $ currentProposalTime # txInfoF.validRange - proposalOutStatus <- tclet $ pfield @"status" # proposalOut + currentTime <- pletC $ currentProposalTime # txInfoF.validRange + proposalOutStatus <- pletC $ pfield @"status" # proposalOut let -- Only the status of proposals should be updated in this case. templateProposalOut = @@ -395,13 +397,13 @@ proposalValidator proposal = .& #startingTime .= proposalF.startingTime ) - tcassert "Only status changes in the output proposal" $ + pguardC "Only status changes in the output proposal" $ templateProposalOut #== proposalOut - inDraftPeriod <- tclet $ isDraftPeriod # proposalF.timingConfig # proposalF.startingTime # currentTime - inVotingPeriod <- tclet $ isVotingPeriod # proposalF.timingConfig # proposalF.startingTime # currentTime - inLockedPeriod <- tclet $ isLockingPeriod # proposalF.timingConfig # proposalF.startingTime # currentTime - inExecutionPeriod <- tclet $ isExecutionPeriod # proposalF.timingConfig # proposalF.startingTime # currentTime + inDraftPeriod <- pletC $ isDraftPeriod # proposalF.timingConfig # proposalF.startingTime # currentTime + inVotingPeriod <- pletC $ isVotingPeriod # proposalF.timingConfig # proposalF.startingTime # currentTime + inLockedPeriod <- pletC $ isLockingPeriod # proposalF.timingConfig # proposalF.startingTime # currentTime + inExecutionPeriod <- pletC $ isExecutionPeriod # proposalF.timingConfig # proposalF.startingTime # currentTime -- Check the timings. let isFinished = proposalF.status #== pconstantData Finished @@ -418,8 +420,8 @@ proposalValidator proposal = PLocked _ -> pnot # inLockedPeriod _ -> pconstant True - tcassert "Cannot advance ahead of time" notTooEarly - tcassert "Finished proposals cannot be advanced" $ pnot # isFinished + pguardC "Cannot advance ahead of time" notTooEarly + pguardC "Finished proposals cannot be advanced" $ pnot # isFinished pure $ pif @@ -430,19 +432,19 @@ proposalValidator proposal = -- TODO: Perform other necessary checks. -- 'Draft' -> 'VotingReady' - tcassert "Proposal status set to VotingReady" $ + pguardC "Proposal status set to VotingReady" $ proposalOutStatus #== pconstantData VotingReady pure $ popaque (pconstant ()) PVotingReady _ -> unTermCont $ do -- 'VotingReady' -> 'Locked' - tcassert "Proposal status set to Locked" $ + pguardC "Proposal status set to Locked" $ proposalOutStatus #== pconstantData Locked pure $ popaque (pconstant ()) PLocked _ -> unTermCont $ do -- 'Locked' -> 'Finished' - tcassert "Proposal status set to Finished" $ + pguardC "Proposal status set to Finished" $ proposalOutStatus #== pconstantData Finished -- TODO: Perform other necessary checks. diff --git a/agora/Agora/Proposal/Time.hs b/agora/Agora/Proposal/Time.hs index 98cb9f2..8e62f93 100644 --- a/agora/Agora/Proposal/Time.hs +++ b/agora/Agora/Proposal/Time.hs @@ -29,7 +29,6 @@ module Agora.Proposal.Time ( isExecutionPeriod, ) where -import Agora.Utils (tcassert, tcmatch) import GHC.Generics qualified as GHC import Generics.SOP (Generic, HasDatatypeInfo, I (I)) import Plutarch.Api.V1 ( @@ -45,6 +44,7 @@ import Plutarch.DataRepr ( PDataFields, PIsDataReprInstances (..), ) +import Plutarch.Extra.TermCont (pguardC, pmatchC) import Plutarch.Lift ( DerivePConstantViaNewtype (..), PConstantDecl, @@ -184,7 +184,7 @@ instance AdditiveSemigroup (Term s PPOSIXTime) where createProposalStartingTime :: forall (s :: S). Term s (PMaxTimeRangeWidth :--> PPOSIXTimeRange :--> PProposalStartingTime) createProposalStartingTime = phoistAcyclic $ plam $ \(pto -> maxDuration) iv -> unTermCont $ do - currentTimeF <- tcmatch $ currentProposalTime # iv + currentTimeF <- pmatchC $ currentProposalTime # iv -- Use the middle of the current time range as the starting time. let duration = currentTimeF.upperBound - currentTimeF.lowerBound @@ -194,7 +194,7 @@ createProposalStartingTime = phoistAcyclic $ # (currentTimeF.lowerBound + currentTimeF.upperBound) # 2 - tcassert "createProposalStartingTime: given time range should be tight enough" $ + pguardC "createProposalStartingTime: given time range should be tight enough" $ duration #<= maxDuration pure $ pcon $ PProposalStartingTime startingTime @@ -207,10 +207,10 @@ createProposalStartingTime = phoistAcyclic $ currentProposalTime :: forall (s :: S). Term s (PPOSIXTimeRange :--> PProposalTime) currentProposalTime = phoistAcyclic $ plam $ \iv -> unTermCont $ do - PInterval iv' <- tcmatch iv + PInterval iv' <- pmatchC iv ivf <- tcont $ pletFields @'["from", "to"] iv' - PLowerBound lb <- tcmatch ivf.from - PUpperBound ub <- tcmatch ivf.to + PLowerBound lb <- pmatchC ivf.from + PUpperBound ub <- pmatchC ivf.to lbf <- tcont $ pletFields @'["_0", "_1"] lb ubf <- tcont $ pletFields @'["_0", "_1"] ub pure $ @@ -243,7 +243,7 @@ proposalTimeWithin :: ) proposalTimeWithin = phoistAcyclic $ plam $ \l h proposalTime' -> unTermCont $ do - PProposalTime ut lt <- tcmatch proposalTime' + PProposalTime ut lt <- pmatchC proposalTime' pure $ foldr1 (#&&) diff --git a/agora/Agora/Stake.hs b/agora/Agora/Stake.hs index b68ea8c..3558d9e 100644 --- a/agora/Agora/Stake.hs +++ b/agora/Agora/Stake.hs @@ -26,6 +26,8 @@ module Agora.Stake ( -------------------------------------------------------------------------------- +import Control.Applicative (Const) +import Data.Tagged (Tagged (..)) import GHC.Generics qualified as GHC import Generics.SOP (Generic, I (I)) import Prelude hiding (Num (..)) @@ -33,6 +35,7 @@ import Prelude hiding (Num (..)) -------------------------------------------------------------------------------- import PlutusLedgerApi.V1 (PubKeyHash) +import PlutusLedgerApi.V1.Value (AssetClass) import PlutusTx qualified -------------------------------------------------------------------------------- @@ -46,30 +49,24 @@ import Plutarch.Api.V1 ( PTxInInfo (PTxInInfo), PTxOut (PTxOut), ) +import Plutarch.Api.V1.AssetClass (PAssetClass, passetClassValueOf) +import Plutarch.Api.V1.ScriptContext (ptryFindDatum) import Plutarch.DataRepr ( DerivePConstantViaData (..), PDataFields, PIsDataReprInstances (PIsDataReprInstances), ) +import Plutarch.Extra.List (pnotNull) +import Plutarch.Extra.TermCont (pletC, pmatchC) import Plutarch.Internal (punsafeCoerce) import Plutarch.Lift (PConstantDecl, PUnsafeLiftDecl (..)) -import PlutusLedgerApi.V1.Value (AssetClass) +import Plutarch.SafeMoney (PDiscrete) +import Plutarch.TryFrom (PTryFrom (PTryFromExcess, ptryFrom')) -------------------------------------------------------------------------------- import Agora.Proposal (PProposalId, PResultTag, ProposalId (..), ResultTag (..)) import Agora.SafeMoney (GTTag) -import Agora.Utils ( - pnotNull, - ptryFindDatum, - tclet, - tcmatch, - ) -import Control.Applicative (Const) -import Data.Tagged (Tagged (..)) -import Plutarch.Api.V1.AssetClass (PAssetClass, passetClassValueOf) -import Plutarch.SafeMoney (PDiscrete) -import Plutarch.TryFrom (PTryFrom (PTryFromExcess, ptryFrom')) -------------------------------------------------------------------------------- @@ -300,10 +297,10 @@ isInputStakeOwnedBy :: ) isInputStakeOwnedBy = plam $ \ac ss datums txInInfo' -> unTermCont $ do - PTxInInfo ((pfield @"resolved" #) -> txOut) <- tcmatch $ pfromData txInInfo' - PTxOut txOut' <- tcmatch txOut + PTxInInfo ((pfield @"resolved" #) -> txOut) <- pmatchC $ pfromData txInInfo' + PTxOut txOut' <- pmatchC txOut txOutF <- tcont $ pletFields @'["value", "datumHash"] txOut' - outStakeST <- tclet $ passetClassValueOf # txOutF.value # ac + outStakeST <- pletC $ passetClassValueOf # txOutF.value # ac pure $ pmatch txOutF.datumHash $ \case PDNothing _ -> pcon PFalse diff --git a/agora/Agora/Stake/Scripts.hs b/agora/Agora/Stake/Scripts.hs index 63d2c03..d0ca147 100644 --- a/agora/Agora/Stake/Scripts.hs +++ b/agora/Agora/Stake/Scripts.hs @@ -12,19 +12,7 @@ import Agora.Stake import Agora.Utils ( mustBePJust, mustFindDatum', - paddValue, - pfindTxInByTxOutRef, - pgeqByClass', - pgeqBySymbol, - psymbolValueOf, - ptokenSpent, - ptxSignedBy, pvalidatorHashToTokenName, - pvalueSpent, - tcassert, - tclet, - tcmatch, - tctryFrom, ) import Data.Tagged (Tagged (..), untag) import Plutarch.Api.V1 ( @@ -40,7 +28,10 @@ import Plutarch.Api.V1 ( mkMintingPolicy, ) import Plutarch.Api.V1.AssetClass (passetClass, passetClassValueOf, pvalueOf) +import Plutarch.Api.V1.ScriptContext (pfindTxInByTxOutRef, pisTokenSpent, ptxSignedBy, pvalueSpent) +import "liqwid-plutarch-extra" Plutarch.Api.V1.Value (pgeqByClass', pgeqBySymbol, psymbolValueOf) import Plutarch.Extra.Record (mkRecordConstr, (.&), (.=)) +import Plutarch.Extra.TermCont (pguardC, pletC, pmatchC, ptryFromC) import Plutarch.Internal (punsafeCoerce) import Plutarch.Numeric.Additive (AdditiveMonoid (zero), AdditiveSemigroup ((+))) import Plutarch.SafeMoney ( @@ -74,24 +65,24 @@ stakePolicy :: stakePolicy gtClassRef = plam $ \_redeemer ctx' -> unTermCont $ do ctx <- tcont $ pletFields @'["txInfo", "purpose"] ctx' - txInfo <- tclet $ ctx.txInfo + txInfo <- pletC $ ctx.txInfo let _a :: Term _ PTxInfo _a = txInfo txInfoF <- tcont $ pletFields @'["mint", "inputs", "outputs", "signatories", "datums"] txInfo - PMinting ownSymbol' <- tcmatch $ pfromData ctx.purpose - ownSymbol <- tclet $ pfield @"_0" # ownSymbol' - spentST <- tclet $ psymbolValueOf # ownSymbol #$ pvalueSpent # txInfoF.inputs - mintedST <- tclet $ psymbolValueOf # ownSymbol # txInfoF.mint + PMinting ownSymbol' <- pmatchC $ pfromData ctx.purpose + ownSymbol <- pletC $ pfield @"_0" # ownSymbol' + spentST <- pletC $ psymbolValueOf # ownSymbol #$ pvalueSpent # txInfoF.inputs + mintedST <- pletC $ psymbolValueOf # ownSymbol # txInfoF.mint let burning = unTermCont $ do - tcassert "ST at inputs must be 1" $ + pguardC "ST at inputs must be 1" $ spentST #== 1 - tcassert "ST burned" $ + pguardC "ST burned" $ mintedST #== -1 - tcassert "An unlocked input existed containing an ST" $ + pguardC "An unlocked input existed containing an ST" $ pany # plam ( \((pfield @"resolved" #) -> txOut) -> unTermCont $ do @@ -109,13 +100,13 @@ stakePolicy gtClassRef = pure $ popaque (pconstant ()) let minting = unTermCont $ do - tcassert "ST at inputs must be 0" $ + pguardC "ST at inputs must be 0" $ spentST #== 0 - tcassert "Minted ST must be exactly 1" $ + pguardC "Minted ST must be exactly 1" $ mintedST #== 1 - tcassert "A UTXO must exist with the correct output" $ + pguardC "A UTXO must exist with the correct output" $ unTermCont $ do let scriptOutputWithStakeST = mustBePJust @@ -214,50 +205,50 @@ stakeValidator :: Stake -> ClosedTerm PValidator stakeValidator stake = plam $ \datum redeemer ctx' -> unTermCont $ do ctx <- tcont $ pletFields @'["txInfo", "purpose"] ctx' - txInfo <- tclet $ pfromData ctx.txInfo + txInfo <- pletC $ pfromData ctx.txInfo txInfoF <- tcont $ pletFields @'["mint", "inputs", "outputs", "signatories", "datums"] txInfo - (pfromData -> stakeRedeemer, _) <- tctryFrom redeemer + (pfromData -> stakeRedeemer, _) <- ptryFromC redeemer -- TODO: Use PTryFrom let stakeDatum' :: Term _ PStakeDatum stakeDatum' = pfromData $ punsafeCoerce datum stakeDatum <- tcont $ pletFields @'["owner", "stakedAmount", "lockedBy"] stakeDatum' - PSpending txOutRef <- tcmatch $ pfromData ctx.purpose + PSpending txOutRef <- pmatchC $ pfromData ctx.purpose - PJust txInInfo <- tcmatch $ pfindTxInByTxOutRef # (pfield @"_0" # txOutRef) # txInfoF.inputs - ownAddress <- tclet $ pfield @"address" #$ pfield @"resolved" # txInInfo + PJust txInInfo <- pmatchC $ pfindTxInByTxOutRef # (pfield @"_0" # txOutRef) # txInfoF.inputs + ownAddress <- pletC $ pfield @"address" #$ pfield @"resolved" # txInInfo let continuingValue :: Term _ (PValue _ _) continuingValue = pfield @"value" #$ pfield @"resolved" # txInInfo -- Whether the owner signs this transaction or not. - ownerSignsTransaction <- tclet $ ptxSignedBy # txInfoF.signatories # stakeDatum.owner + ownerSignsTransaction <- pletC $ ptxSignedBy # txInfoF.signatories # stakeDatum.owner - stCurrencySymbol <- tclet $ pconstant $ mintingPolicySymbol $ mkMintingPolicy (stakePolicy stake.gtClassRef) - mintedST <- tclet $ psymbolValueOf # stCurrencySymbol # txInfoF.mint - valueSpent <- tclet $ pvalueSpent # txInfoF.inputs - spentST <- tclet $ psymbolValueOf # stCurrencySymbol #$ valueSpent + stCurrencySymbol <- pletC $ pconstant $ mintingPolicySymbol $ mkMintingPolicy (stakePolicy stake.gtClassRef) + mintedST <- pletC $ psymbolValueOf # stCurrencySymbol # txInfoF.mint + valueSpent <- pletC $ pvalueSpent # txInfoF.inputs + spentST <- pletC $ psymbolValueOf # stCurrencySymbol #$ valueSpent let AssetClass (propCs, propTn) = stake.proposalSTClass proposalSTClass = passetClass # pconstant propCs # pconstant propTn - spentProposalST <- tclet $ passetClassValueOf # valueSpent # proposalSTClass + spentProposalST <- pletC $ passetClassValueOf # valueSpent # proposalSTClass -- Is the stake currently locked? - stakeIsLocked <- tclet $ stakeLocked # stakeDatum' + stakeIsLocked <- pletC $ stakeLocked # stakeDatum' pure $ pmatch stakeRedeemer $ \case PDestroy _ -> unTermCont $ do - tcassert "ST at inputs must be 1" $ + pguardC "ST at inputs must be 1" $ spentST #== 1 - tcassert "Should burn ST" $ + pguardC "Should burn ST" $ mintedST #== -1 - tcassert "Stake unlocked" $ pnot # stakeIsLocked + pguardC "Stake unlocked" $ pnot # stakeIsLocked - tcassert "Owner signs this transaction" ownerSignsTransaction + pguardC "Owner signs this transaction" ownerSignsTransaction pure $ popaque (pconstant ()) -------------------------------------------------------------------------- @@ -265,7 +256,7 @@ stakeValidator stake = _ -> unTermCont $ do -- Filter out own output with own address and PST. ownOutput <- - tclet $ + pletC $ mustBePJust # "Own output should be present" #$ pfind # plam ( \input -> unTermCont $ do @@ -277,39 +268,39 @@ stakeValidator stake = # pfromData txInfoF.outputs stakeOut <- - tclet $ + pletC $ mustFindDatum' @PStakeDatum # (pfield @"datumHash" # ownOutput) # txInfoF.datums ownOutputValue <- - tclet $ + pletC $ pfield @"value" # ownOutput ownOutputValueUnchanged <- - tclet $ + pletC $ pdata continuingValue #== pdata ownOutputValue stakeOutUnchanged <- - tclet $ + pletC $ pdata stakeOut #== pdata stakeDatum' pure $ pmatch stakeRedeemer $ \case PRetractVotes _ -> unTermCont $ do - tcassert + pguardC "Owner signs this transaction" ownerSignsTransaction - tcassert "ST at inputs must be 1" $ + pguardC "ST at inputs must be 1" $ spentST #== 1 -- This puts trust into the Proposal. The Proposal must necessarily check -- that this is not abused. - tcassert "Proposal ST spent" $ + pguardC "Proposal ST spent" $ spentProposalST #== 1 - tcassert "A UTXO must exist with the correct output" $ + pguardC "A UTXO must exist with the correct output" $ unTermCont $ do let valueCorrect = ownOutputValueUnchanged @@ -324,13 +315,13 @@ stakeValidator stake = pure $ popaque (pconstant ()) -------------------------------------------------------------------------- PPermitVote l -> unTermCont $ do - tcassert + pguardC "Owner signs this transaction" ownerSignsTransaction -- This puts trust into the Proposal. The Proposal must necessarily check -- that this is not abused. - tcassert "Proposal ST spent" $ + pguardC "Proposal ST spent" $ spentProposalST #== 1 -- Update the stake datum, but only the 'lockedBy' field. @@ -342,7 +333,7 @@ stakeValidator stake = expectedLocks = pcons # newLock # stakeDatum.lockedBy expectedDatum <- - tclet $ + pletC $ mkRecordConstr PStakeDatum ( #stakedAmount .= stakeDatum.stakedAmount @@ -350,7 +341,7 @@ stakeValidator stake = .& #lockedBy .= pdata expectedLocks ) - tcassert "A UTXO must exist with the correct output" $ + pguardC "A UTXO must exist with the correct output" $ let correctOutputDatum = stakeOut #== expectedDatum valueCorrect = ownOutputValueUnchanged in foldl1 @@ -362,24 +353,24 @@ stakeValidator stake = pure $ popaque (pconstant ()) -------------------------------------------------------------------------- PWitnessStake _ -> unTermCont $ do - tcassert "ST at inputs must be 1" $ + pguardC "ST at inputs must be 1" $ spentST #== 1 let AssetClass (propCs, propTn) = stake.proposalSTClass propAssetClass = passetClass # pconstant propCs # pconstant propTn proposalTokenMoved = - ptokenSpent + pisTokenSpent # propAssetClass # txInfoF.inputs -- In order for cosignature to be witnessed, it must be possible for a -- proposal to allow this transaction to happen. This puts trust into the Proposal. -- The Proposal must necessarily check that this is not abused. - tcassert + pguardC "Owner signs this transaction OR proposal token is spent" (ownerSignsTransaction #|| proposalTokenMoved) - tcassert "A UTXO must exist with the correct output" $ + pguardC "A UTXO must exist with the correct output" $ let correctOutputDatum = stakeOutUnchanged valueCorrect = ownOutputValueUnchanged in foldl1 @@ -390,21 +381,21 @@ stakeValidator stake = pure $ popaque (pconstant ()) -------------------------------------------------------------------------- PDepositWithdraw r -> unTermCont $ do - tcassert "ST at inputs must be 1" $ + pguardC "ST at inputs must be 1" $ spentST #== 1 - tcassert "Stake unlocked" $ + pguardC "Stake unlocked" $ pnot #$ stakeIsLocked - tcassert + pguardC "Owner signs this transaction" ownerSignsTransaction - tcassert "A UTXO must exist with the correct output" $ + pguardC "A UTXO must exist with the correct output" $ unTermCont $ do let oldStakedAmount = pfromData $ stakeDatum.stakedAmount delta = pfromData $ pfield @"delta" # r - newStakedAmount <- tclet $ oldStakedAmount + delta + newStakedAmount <- pletC $ oldStakedAmount + delta - tcassert "New staked amount shoudl be greater than or equal to 0" $ + pguardC "New staked amount shoudl be greater than or equal to 0" $ zero #<= newStakedAmount let expectedDatum = @@ -420,7 +411,7 @@ stakeValidator stake = valueDelta = pdiscreteValue' stake.gtClassRef # delta expectedValue = - paddValue # continuingValue # valueDelta + continuingValue <> valueDelta valueCorrect = foldr1 diff --git a/agora/Agora/Treasury.hs b/agora/Agora/Treasury.hs index f750aef..a63df8f 100644 --- a/agora/Agora/Treasury.hs +++ b/agora/Agora/Treasury.hs @@ -11,7 +11,6 @@ treasury. module Agora.Treasury (module Agora.Treasury) where import Agora.AuthorityToken (singleAuthorityTokenBurned) -import Agora.Utils (tcassert, tclet, tcmatch, tctryFrom) import GHC.Generics qualified as GHC import Generics.SOP import Plutarch.Api.V1 (PValidator) @@ -21,6 +20,7 @@ import Plutarch.DataRepr ( DerivePConstantViaData (..), PIsDataReprInstances (PIsDataReprInstances), ) +import Plutarch.Extra.TermCont (pguardC, pletC, pmatchC, ptryFromC) import Plutarch.Lift (PConstantDecl (..), PLifted (..), PUnsafeLiftDecl) import Plutarch.TryFrom () import PlutusLedgerApi.V1.Value (CurrencySymbol) @@ -76,26 +76,26 @@ treasuryValidator :: CurrencySymbol -> ClosedTerm PValidator treasuryValidator gatCs' = plam $ \_datum redeemer ctx' -> unTermCont $ do - (treasuryRedeemer, _) <- tctryFrom redeemer + (treasuryRedeemer, _) <- ptryFromC redeemer -- plet required fields from script context. ctx <- tcont $ pletFields @["txInfo", "purpose"] ctx' -- Ensure that script is for burning i.e. minting a negative amount. - PMinting _ <- tcmatch ctx.purpose + PMinting _ <- pmatchC ctx.purpose -- Ensure redeemer type is valid. - PSpendTreasuryGAT _ <- tcmatch $ pfromData treasuryRedeemer + PSpendTreasuryGAT _ <- pmatchC $ pfromData treasuryRedeemer -- Get the minted value from txInfo. - txInfo' <- tclet ctx.txInfo + txInfo' <- pletC ctx.txInfo txInfo <- tcont $ pletFields @'["mint"] txInfo' let mint :: Term _ (PValue _ _) mint = txInfo.mint - gatCs <- tclet $ pconstant gatCs' + gatCs <- pletC $ pconstant gatCs' - tcassert "A single authority token has been burned" $ + pguardC "A single authority token has been burned" $ singleAuthorityTokenBurned gatCs txInfo' mint pure . popaque $ pconstant () diff --git a/agora/Agora/Utils.hs b/agora/Agora/Utils.hs index 13e0088..9425da2 100644 --- a/agora/Agora/Utils.hs +++ b/agora/Agora/Utils.hs @@ -6,45 +6,6 @@ Description: Plutarch utility functions that should be upstreamed or don't belon Plutarch utility functions that should be upstreamed or don't belong anywhere else. -} module Agora.Utils ( - -- * TermCont-based combinators. Some of these will live in plutarch eventually. - tcassert, - tclet, - tcmatch, - tctryFrom, - - -- * Validator-level utility functions - pfind', - pfindDatum, - ptryFindDatum, - pvalueSpent, - ptxSignedBy, - paddValue, - plookup, - pfromMaybe, - psymbolValueOf, - pgeqByClass, - pgeqBySymbol, - pgeqByClass', - pfindTxInByTxOutRef, - psingletonValue, - pfindMap, - pnotNull, - pisJust, - ptokenSpent, - pkeysEqual, - pnubSortBy, - pisUniq, - pisUniqBy, - pisDJust, - pisUTXOSpent, - pmsortBy, - pmsort, - pnubSort, - pupdate, - pmapMap, - pmapMaybe, - - -- * Functions which should (probably) not be upstreamed findTxOutByTxOutRef, scriptHashFromAddress, findOutputsToAddress, @@ -57,10 +18,9 @@ module Agora.Utils ( mustBePJust, mustBePDJust, validatorHashToAddress, - pmergeBy, - phalve, isScriptAddress, isPubKey, + psingletonValue, ) where -------------------------------------------------------------------------------- @@ -72,541 +32,37 @@ import PlutusLedgerApi.V1 ( TokenName (..), ValidatorHash (..), ) -import PlutusLedgerApi.V1.Value (AssetClass (..)) -------------------------------------------------------------------------------- import Plutarch.Api.V1 ( - AmountGuarantees (NoGuarantees, NonZero, Positive), - KeyGuarantees (Sorted, Unsorted), + AmountGuarantees, + KeyGuarantees, PAddress, PCredential (PScriptCredential), PCurrencySymbol, PDatum, PDatumHash, - PMap, PMaybeData (PDJust), PMintingPolicy, - PPubKeyHash, PTokenName (PTokenName), PTuple, - PTxInInfo (PTxInInfo), - PTxOut (PTxOut), + PTxInInfo, + PTxOut, PTxOutRef, PValidatorHash, PValue, mintingPolicySymbol, mkMintingPolicy, ) -import Plutarch.Api.V1.AssetClass (PAssetClass, passetClassValueOf, pvalueOf) import Plutarch.Api.V1.AssocMap (PMap (PMap)) +import Plutarch.Api.V1.ScriptContext (pfindDatum, pfindTxInByTxOutRef) +import "liqwid-plutarch-extra" Plutarch.Api.V1.Value (psymbolValueOf) import "plutarch" Plutarch.Api.V1.Value (PValue (PValue)) import Plutarch.Builtin (pforgetData, ppairDataBuiltin) -import Plutarch.Extra.Map (pkeys) -import Plutarch.Reducible (Reducible (Reduce)) -import Plutarch.TryFrom (PTryFrom (PTryFromExcess)) -import Plutarch.Unsafe (punsafeCoerce) +import Plutarch.Extra.List (plookupTuple) +import Plutarch.Extra.TermCont (pletC, pmatchC) --------------------------------------------------------------------------------- --- TermCont-based combinators. Some of these will live in plutarch eventually. - --- | Assert a particular 'PBool', trace if false. -tcassert :: forall r (s :: S). Term s PString -> Term s PBool -> TermCont @r s () -tcassert errorMessage check = tcont $ \k -> pif check (k ()) (ptraceError errorMessage) - --- | 'plet' but for use in 'TermCont'. -tclet :: forall r (s :: S) (a :: PType). Term s a -> TermCont @r s (Term s a) -tclet = tcont . plet - --- | 'pmatch' but for use in 'TermCont'. -tcmatch :: forall (a :: PType) (s :: S). PlutusType a => Term s a -> TermCont s (a s) -tcmatch = tcont . pmatch - --- | 'ptryFrom' but for use in 'TermCont'. -tctryFrom :: forall b a s r. PTryFrom a b => Term s a -> TermCont @r s (Term s b, Reduce (PTryFromExcess a b s)) -tctryFrom = tcont . ptryFrom - --- | Escape with a particular value on expecting 'Just'. For use in monadic context. -tcexpectJust :: - forall r (a :: PType) (s :: S). - Term s r -> - Term s (PMaybe a) -> - TermCont @r s (Term s a) -tcexpectJust escape ma = tcont $ \f -> - pmatch ma $ \case - PJust v -> f v - PNothing -> escape - --------------------------------------------------------------------------------- --- Validator-level utility functions - --- | Find a datum with the given hash. -pfindDatum :: Term s (PDatumHash :--> PBuiltinList (PAsData (PTuple PDatumHash PDatum)) :--> PMaybe PDatum) -pfindDatum = phoistAcyclic $ - plam $ \datumHash datums -> plookupTuple # datumHash # datums - --- | Find a datum with the given hash, and `ptryFrom` it. -ptryFindDatum :: forall (a :: PType) (s :: S). PTryFrom PData a => Term s (PDatumHash :--> PBuiltinList (PAsData (PTuple PDatumHash PDatum)) :--> PMaybe a) -ptryFindDatum = phoistAcyclic $ - plam $ \datumHash inputs -> - pmatch (pfindDatum # datumHash # inputs) $ \case - PNothing -> pcon PNothing - PJust datum -> unTermCont $ do - (datum', _) <- tctryFrom (pto datum) - pure $ pcon (PJust datum') - --- | Check if a PubKeyHash signs this transaction. -ptxSignedBy :: Term s (PBuiltinList (PAsData PPubKeyHash) :--> PAsData PPubKeyHash :--> PBool) -ptxSignedBy = phoistAcyclic $ - plam $ \sigs sig -> pelem # sig # sigs - --- | Get the first element that matches a predicate or return Nothing. -pfind' :: - PIsListLike list a => - (Term s a -> Term s PBool) -> - Term s (list a :--> PMaybe a) -pfind' p = - precList - (\self x xs -> pif (p x) (pcon (PJust x)) (self # xs)) - (const $ pcon PNothing) - --- | Get the first element that maps to a PJust in a list. -pfindMap :: - PIsListLike list a => - Term s ((a :--> PMaybe b) :--> list a :--> PMaybe b) -pfindMap = - phoistAcyclic $ - plam $ \p -> - precList - ( \self x xs -> - -- In the future, this should use `pmatchSum`, I believe? - pmatch (p # x) $ \case - PNothing -> self # xs - PJust v -> pcon (PJust v) - ) - (const $ pcon PNothing) - --- | Find the value for a given key in an associative list. -plookup :: - (PEq a, PIsListLike list (PBuiltinPair a b)) => - Term s (a :--> list (PBuiltinPair a b) :--> PMaybe b) -plookup = - phoistAcyclic $ - plam $ \k xs -> - pmatch (pfind' (\p -> pfstBuiltin # p #== k) # xs) $ \case - PNothing -> pcon PNothing - PJust p -> pcon (PJust (psndBuiltin # p)) - --- | Find the value for a given key in an assoclist which uses 'PTuple's. -plookupTuple :: - (PEq a, PIsListLike list (PAsData (PTuple a b)), PIsData a, PIsData b) => - Term s (a :--> list (PAsData (PTuple a b)) :--> PMaybe b) -plookupTuple = - phoistAcyclic $ - plam $ \k xs -> - pmatch (pfind' (\p -> (pfield @"_0" # pfromData p) #== k) # xs) $ \case - PNothing -> pcon PNothing - PJust p -> pcon (PJust (pfield @"_1" # pfromData p)) - --- | Extract a Maybe by providing a default value in case of Just. -pfromMaybe :: forall a s. Term s (a :--> PMaybe a :--> a) -pfromMaybe = phoistAcyclic $ - plam $ \e a -> - pmatch a $ \case - PJust a' -> a' - PNothing -> e - --- | Yield True if a given PMaybe is of form @'PJust' _@. -pisJust :: forall a s. Term s (PMaybe a :--> PBool) -pisJust = phoistAcyclic $ - plam $ \v' -> - pmatch v' $ \case - PJust _ -> pconstant True - PNothing -> pconstant False - --- | Get the sum of all values belonging to a particular CurrencySymbol. -psymbolValueOf :: - forall (keys :: KeyGuarantees) (amounts :: AmountGuarantees) (s :: S). - Term s (PCurrencySymbol :--> PValue keys amounts :--> PInteger) -psymbolValueOf = - phoistAcyclic $ - plam $ \sym value'' -> unTermCont $ do - PValue value' <- tcmatch value'' - PMap value <- tcmatch value' - m' <- tcexpectJust 0 (plookup # pdata sym # value) - PMap m <- tcmatch (pfromData m') - pure $ pfoldr # plam (\x v -> pfromData (psndBuiltin # x) + v) # 0 # m - --- | Extract amount from PValue belonging to a Haskell-level AssetClass. -passetClassValueOf' :: - forall (keys :: KeyGuarantees) (amounts :: AmountGuarantees) (s :: S). - AssetClass -> - Term s (PValue keys amounts :--> PInteger) -passetClassValueOf' (AssetClass (sym, token)) = - phoistAcyclic $ plam $ \value -> pvalueOf # value # pconstant sym # pconstant token - --- | Return '>=' on two values comparing by only a particular AssetClass. -pgeqByClass :: - forall (keys :: KeyGuarantees) (amounts :: AmountGuarantees) (s :: S). - Term s (PCurrencySymbol :--> PTokenName :--> PValue keys amounts :--> PValue keys amounts :--> PBool) -pgeqByClass = - phoistAcyclic $ - plam $ \cs tn a b -> - pvalueOf # b # cs # tn #<= pvalueOf # a # cs # tn - --- | Return '>=' on two values comparing by only a particular CurrencySymbol. -pgeqBySymbol :: - forall (keys :: KeyGuarantees) (amounts :: AmountGuarantees) (s :: S). - Term s (PCurrencySymbol :--> PValue keys amounts :--> PValue keys amounts :--> PBool) -pgeqBySymbol = - phoistAcyclic $ - plam $ \cs a b -> - psymbolValueOf # cs # b #<= psymbolValueOf # cs # a - --- | Return '>=' on two values comparing by only a particular Haskell-level AssetClass. -pgeqByClass' :: - forall (keys :: KeyGuarantees) (amounts :: AmountGuarantees) (s :: S). - AssetClass -> - Term s (PValue keys amounts :--> PValue keys amounts :--> PBool) -pgeqByClass' ac = - phoistAcyclic $ - plam $ \a b -> - passetClassValueOf' ac # b #<= passetClassValueOf' ac # a - --- | Union two maps using a merge function on collisions. -pmapUnionWith :: - forall (k :: PType) (v :: PType) (keys :: KeyGuarantees) (s :: S). - PIsData v => - Term s ((v :--> v :--> v) :--> PMap keys k v :--> PMap keys k v :--> PMap keys k v) -pmapUnionWith = phoistAcyclic $ - -- TODO: this function is kinda suspect. I feel like a lot of optimizations could be done here - plam $ \f xs' ys' -> unTermCont $ do - PMap xs <- tcmatch xs' - PMap ys <- tcmatch ys' - let ls = - pmap - # plam - ( \p -> unTermCont $ do - pf <- tclet $ pfstBuiltin # p - pure $ - pmatch (plookup # pf # ys) $ \case - PJust v -> - -- Data conversions here are silly, aren't they? - ppairDataBuiltin # pf # pdata (f # pfromData (psndBuiltin # p) # pfromData v) - PNothing -> p - ) - # xs - rs = - pfilter - # plam - ( \p -> - pnot #$ pany # plam (\p' -> pfstBuiltin # p' #== pfstBuiltin # p) # xs - ) - # ys - pure $ pcon (PMap $ pconcat # ls # rs) - --- | A special version of `pmap` which allows list elements to be thrown out. -pmapMaybe :: forall s a list. (PIsListLike list a) => Term s ((a :--> PMaybe a) :--> list a :--> list a) -pmapMaybe = phoistAcyclic $ - pfix #$ plam $ \self f l -> pif (pnull # l) pnil $ - unTermCont $ do - x <- tclet $ phead # l - xs <- tclet $ ptail # l - - pure $ - pmatch (f # x) $ \case - PJust ux -> pcons # ux #$ self # f # xs - _ -> self # f # xs - --- | / O(n) /. Update the value at a given key in a `PMap`, have the same functionalities as 'Data.Map.update'. -pupdate :: - forall (k :: PType) (v :: PType) (keys :: KeyGuarantees) (s :: S). - (PIsData k, PIsData v) => - Term s ((v :--> PMaybe v) :--> k :--> PMap keys k v :--> PMap keys k v) -pupdate = phoistAcyclic $ - plam $ \f (pdata -> tk) (pto -> (ps :: Term _ (PBuiltinList _))) -> - pcon $ - PMap $ - pmapMaybe - # plam - ( \kv -> - let k = pfstBuiltin # kv - v = pfromData $ psndBuiltin # kv - in pif - (k #== tk) - -- 'PBuiltinPair' doesn't have 'PFunctor', so: - ( pmatch (f # v) $ - \case - PJust uv -> pcon $ PJust $ ppairDataBuiltin # k # pdata uv - _ -> pcon PNothing - ) - (pcon $ PJust kv) - ) - # ps - --- | / O(n) /. Map a function over all values in a 'PMap'. -pmapMap :: - forall (k :: PType) (a :: PType) (b :: PType) (keys :: KeyGuarantees) (s :: S). - (PIsData k, PIsData a, PIsData b) => - Term s ((a :--> b) :--> PMap keys k a :--> PMap keys k b) -pmapMap = phoistAcyclic $ - plam $ \f (pto -> (ps :: Term _ (PBuiltinList _))) -> - pcon $ - PMap $ - pmap - # plam - ( \kv -> - let k = pfstBuiltin # kv - v = psndBuiltin # kv - - nv = pdata $ f # pfromData v - in ppairDataBuiltin # k # nv - ) - # ps - --- | Compute the guarantees known after adding two values. -type family AddGuarantees (a :: AmountGuarantees) (b :: AmountGuarantees) where - AddGuarantees 'Positive 'Positive = 'Positive - AddGuarantees _ _ = 'NoGuarantees - --- | Add two 'PValue's together. -paddValue :: - forall (keys :: KeyGuarantees) (as :: AmountGuarantees) (bs :: AmountGuarantees) (s :: S). - Term s (PValue keys as :--> PValue keys bs :--> PValue keys (AddGuarantees as bs)) -paddValue = phoistAcyclic $ - plam $ \a' b' -> unTermCont $ do - PValue a <- tcmatch a' - PValue b <- tcmatch b' - pure $ - pcon - ( PValue $ - pmapUnionWith # plam (\a' b' -> pmapUnionWith # plam (+) # a' # b') # a # b - ) - --- | Sum of all value at input. -pvalueSpent :: - forall (s :: S). - Term s (PBuiltinList (PAsData PTxInInfo) :--> PValue 'Sorted 'Positive) -pvalueSpent = phoistAcyclic $ - plam $ \inputs -> - pfoldr - # plam - ( \txInInfo' v -> - pmatch - (pfromData txInInfo') - $ \(PTxInInfo txInInfo) -> - paddValue - # pmatch - (pfield @"resolved" # txInInfo) - (\(PTxOut o) -> pfromData $ pfield @"value" # o) - # v - ) - -- TODO: This should be possible without coercions, but I can't figure out the types atm. - # punsafeCoerce (pconstant mempty :: Term _ (PValue 'Unsorted 'NonZero)) - # inputs - --- | Find the TxInInfo by a TxOutRef. -pfindTxInByTxOutRef :: Term s (PTxOutRef :--> PBuiltinList (PAsData PTxInInfo) :--> PMaybe PTxInInfo) -pfindTxInByTxOutRef = phoistAcyclic $ - plam $ \txOutRef inputs -> - pfindMap - # plam - ( \txInInfo' -> - plet (pfromData txInInfo') $ \r -> - pmatch r $ \(PTxInInfo txInInfo) -> - pif - (pdata txOutRef #== pfield @"outRef" # txInInfo) - (pcon (PJust r)) - (pcon PNothing) - ) - #$ inputs - --- | True if a list is not empty. -pnotNull :: forall list a. PIsListLike list a => Term _ (list a :--> PBool) -pnotNull = phoistAcyclic $ plam $ pelimList (\_ _ -> pcon PTrue) (pcon PFalse) - -{- | Check if a particular asset class has been spent in the input list. - - When using this as an authority check, you __MUST__ ensure the authority - knows how to ensure its end of the contract. --} -ptokenSpent :: forall {s :: S}. Term s (PAssetClass :--> PBuiltinList (PAsData PTxInInfo) :--> PBool) -ptokenSpent = - plam $ \tokenClass inputs -> - 0 - #< pfoldr @PBuiltinList - # plam - ( \txInInfo' acc -> unTermCont $ do - PTxInInfo txInInfo <- tcmatch (pfromData txInInfo') - PTxOut txOut' <- tcmatch $ pfromData $ pfield @"resolved" # txInInfo - txOut <- tcont $ pletFields @'["value"] txOut' - let txOutValue = pfromData txOut.value - pure $ acc + passetClassValueOf # txOutValue # tokenClass - ) - # 0 - # inputs - -{- | True if both maps have exactly the same keys. - Using @'#=='@ is not sufficient, because keys returned are not ordered. --} -pkeysEqual :: - forall (k :: PType) (a :: PType) (b :: PType) (keys :: KeyGuarantees) (s :: S). - (POrd k, PIsData k) => - Term s (PMap keys k a :--> PMap keys k b :--> PBool) -pkeysEqual = phoistAcyclic $ - plam $ \p q -> unTermCont $ do - pks <- tclet $ pkeys # p - qks <- tclet $ pkeys # q - - pure $ - pif - (plength # pks #== plength # qks) - ( unTermCont $ do - let comp = phoistAcyclic $ plam $ \(pfromData -> x) (pfromData -> y) -> x #< y - spks = pmsortBy # comp # pks - sqks = pmsortBy # comp # qks - - pure $ plistEquals # spks # sqks - ) - (pcon PFalse) - --- | / O(nlogn) /. Sort and remove dupicate elements in a list. -pnubSortBy :: - forall list a (s :: S). - (PIsListLike list a) => - Term s ((a :--> a :--> PBool) :--> (a :--> a :--> PBool) :--> list a :--> list a) -pnubSortBy = phoistAcyclic $ - plam $ \eq comp l -> pif (pnull # l) l $ - unTermCont $ do - sl <- tclet $ pmsortBy # comp # l - - let x = phead # sl - xs = ptail # sl - - return $ pgo # eq # x # xs - where - pgo = phoistAcyclic pfix #$ plam pgo' - pgo' self eq seen l = - pif (pnull # l) (psingleton # seen) $ - unTermCont $ do - x <- tclet $ phead # l - xs <- tclet $ ptail # l - - return $ - pif - (eq # x # seen) - (self # eq # seen # xs) - (pcons # seen #$ self # eq # x # xs) - --- | Special version of 'pnubSortBy', which requires elements have 'POrd'. -pnubSort :: - forall list a (s :: S). - (PIsListLike list a, POrd a) => - Term s (list a :--> list a) -pnubSort = phoistAcyclic $ pnubSortBy # eq # comp - where - eq = phoistAcyclic $ plam (#==) - comp = phoistAcyclic $ plam (#<) - --- | / O(nlogn) /. Check if a list contains no duplicates. -pisUniqBy :: - forall list a (s :: S). - (PIsListLike list a) => - Term s ((a :--> a :--> PBool) :--> (a :--> a :--> PBool) :--> list a :--> PBool) -pisUniqBy = phoistAcyclic $ - plam $ \eq comp xs -> - let nubbed = pnubSortBy # eq # comp # xs - in plength # xs #== plength # nubbed - --- | A special case of 'pisUniqBy' which requires elements have 'POrd' instance. -pisUniq :: forall list a (s :: S). (POrd a, PIsListLike list a) => Term s (list a :--> PBool) -pisUniq = phoistAcyclic $ pisUniqBy # eq # comp - where - eq = phoistAcyclic $ plam (#==) - comp = phoistAcyclic $ plam (#<) - --- | Yield True if a given PMaybeData is of form @'PDJust' _@. -pisDJust :: Term s (PMaybeData a :--> PBool) -pisDJust = phoistAcyclic $ - plam $ \x -> - pmatch - x - ( \case - PDJust _ -> pconstant True - _ -> pconstant False - ) - --- | Determines if a given UTXO is spent. -pisUTXOSpent :: Term s (PTxOutRef :--> PBuiltinList (PAsData PTxInInfo) :--> PBool) -pisUTXOSpent = phoistAcyclic $ - plam $ \oref inputs -> P.do - pisJust #$ pfindTxInByTxOutRef # oref # inputs - --- | / O(n) /. Merge two lists which are assumed to be ordered, given a custom comparator. -pmergeBy :: (PIsListLike l a) => Term s ((a :--> a :--> PBool) :--> l a :--> l a :--> l a) -pmergeBy = phoistAcyclic $ pfix #$ plam pmergeBy' - where - pmergeBy' self comp a b = - pif (pnull # a) b $ - pif (pnull # b) a $ - unTermCont $ do - ah <- tclet $ phead # a - at <- tclet $ ptail # a - bh <- tclet $ phead # b - bt <- tclet $ ptail # b - - pure $ - pif - (comp # ah # bh) - (pcons # ah #$ self # comp # at # b) - (pcons # bh #$ self # comp # a # bt) - -{- | / O(nlogn) /. Merge sort, bottom-up version, given a custom comparator. - - Elements are arranged from lowest to highest, - keeping duplicates in the order they appeared in the input. --} -pmsortBy :: (PIsListLike l a) => Term s ((a :--> a :--> PBool) :--> l a :--> l a) -pmsortBy = phoistAcyclic $ pfix #$ plam pmsortBy' - where - pmsortBy' self comp xs = pif (pnull # xs) pnil $ - pif (pnull #$ ptail # xs) xs $ - pmatch (phalve # xs) $ \(PPair fh sh) -> - let sfh = self # comp # fh - ssh = self # comp # sh - in pmergeBy # comp # sfh # ssh - --- | A special case of 'pmsortBy' which requires elements have 'POrd' instance. -pmsort :: (POrd a, PIsListLike l a) => Term s (l a :--> l a) -pmsort = phoistAcyclic $ pmsortBy # comp - where - comp = phoistAcyclic $ plam (#<) - --- | Split a list in half. -phalve :: (PIsListLike l a) => Term s (l a :--> PPair (l a) (l a)) -phalve = phoistAcyclic $ plam $ \l -> go # l # l - where - go = phoistAcyclic $ pfix #$ plam go' - go' self xs ys = - pif - (pnull # ys) - (pcon $ PPair pnil xs) - ( unTermCont $ do - yt <- tclet $ ptail # ys - - xh <- tclet $ phead # xs - xt <- tclet $ ptail # xs - - pure $ - pif (pnull # yt) (pcon $ PPair (psingleton # xh) xt) $ - unTermCont $ do - yt' <- tclet $ ptail # yt - pure $ - pmatch (self # xt # yt') $ \(PPair first last) -> - pcon $ PPair (pcons # xh # first) last - ) - --------------------------------------------------------------------------------- {- Functions which should (probably) not be upstreamed All of these functions are quite inefficient. -} @@ -655,7 +111,7 @@ isPubKey = phoistAcyclic $ findOutputsToAddress :: Term s (PBuiltinList (PAsData PTxOut) :--> PAddress :--> PBuiltinList (PAsData PTxOut)) findOutputsToAddress = phoistAcyclic $ plam $ \outputs address' -> unTermCont $ do - address <- tclet $ pdata address' + address <- pletC $ pdata address' pure $ pfilter # plam (\(pfromData -> txOut) -> pfield @"address" # txOut #== address) # outputs @@ -664,7 +120,7 @@ findOutputsToAddress = phoistAcyclic $ findTxOutDatum :: Term s (PBuiltinList (PAsData (PTuple PDatumHash PDatum)) :--> PTxOut :--> PMaybe PDatum) findTxOutDatum = phoistAcyclic $ plam $ \datums out -> unTermCont $ do - datumHash' <- tcmatch $ pfromData $ pfield @"datumHash" # out + datumHash' <- pmatchC $ pfromData $ pfield @"datumHash" # out pure $ case datumHash' of PDJust ((pfield @"_0" #) -> datumHash) -> pfindDatum # datumHash # datums _ -> pcon PNothing diff --git a/bench.csv b/bench.csv index e739ddf..b3c1eff 100644 --- a/bench.csv +++ b/bench.csv @@ -1,29 +1,29 @@ name,cpu,mem,size -Agora/Effects/Treasury Withdrawal Effect/effect/Simple,317467035,778238,3172 -Agora/Effects/Treasury Withdrawal Effect/effect/Simple with multiple treasuries ,555940189,1350738,3499 -Agora/Effects/Treasury Withdrawal Effect/effect/Mixed Assets,488765974,1174701,3364 -Agora/Effects/Governor Mutation Effect/validator/valid new governor datum/governor validator should pass,83689582,228928,7629 +Agora/Effects/Treasury Withdrawal Effect/effect/Simple,289461528,703055,3191 +Agora/Effects/Treasury Withdrawal Effect/effect/Simple with multiple treasuries ,448521458,1070167,3518 +Agora/Effects/Treasury Withdrawal Effect/effect/Mixed Assets,408085321,966048,3383 +Agora/Effects/Governor Mutation Effect/validator/valid new governor datum/governor validator should pass,83758582,229228,7665 Agora/Effects/Governor Mutation Effect/validator/valid new governor datum/effect validator should pass,97345575,266935,3358 -Agora/Stake/policy/stakeCreation,43459609,126049,2116 -Agora/Stake/validator/stakeDepositWithdraw deposit,226083166,599197,4024 -Agora/Stake/validator/stakeDepositWithdraw withdraw,226083166,599197,4016 -Agora/Proposal/policy/proposalCreation,23071177,68894,1523 -Agora/Proposal/validator/cosignature/proposal,190181087,511819,5644 -Agora/Proposal/validator/cosignature/stake,162540553,402961,4561 -Agora/Proposal/validator/voting/proposal,181998338,491168,5652 -Agora/Proposal/validator/voting/stake,127693475,328703,4614 -Agora/Proposal/validator/advancing/successfully advance to next state/Draft -> VotringReady,98071575,260351,5030 -Agora/Proposal/validator/advancing/successfully advance to next state/VotingReady -> Locked,97228153,258848,5033 -Agora/Proposal/validator/advancing/successfully advance to next state/Locked -> Finished,98924620,262454,5033 -Agora/Proposal/validator/advancing/successfully advance to failed state: timeout/Draft -> Finished,96941774,257621,5032 -Agora/Proposal/validator/advancing/successfully advance to failed state: timeout/VotingReady -> Finished,95532863,254916,5033 -Agora/Proposal/validator/advancing/successfully advance to failed state: timeout/Locked -> Finished,96663841,257320,5033 +Agora/Stake/policy/stakeCreation,43114609,124549,2094 +Agora/Stake/validator/stakeDepositWithdraw deposit,171823342,464745,4069 +Agora/Stake/validator/stakeDepositWithdraw withdraw,171823342,464745,4061 +Agora/Proposal/policy/proposalCreation,23140177,69194,1525 +Agora/Proposal/validator/cosignature/proposal,147258436,403167,5646 +Agora/Proposal/validator/cosignature/stake,117270039,287783,4606 +Agora/Proposal/validator/voting/proposal,154824944,415642,5654 +Agora/Proposal/validator/voting/stake,99545453,256941,4659 +Agora/Proposal/validator/advancing/successfully advance to next state/Draft -> VotringReady,94701799,249495,5031 +Agora/Proposal/validator/advancing/successfully advance to next state/VotingReady -> Locked,93858377,247992,5034 +Agora/Proposal/validator/advancing/successfully advance to next state/Locked -> Finished,95554844,251598,5034 +Agora/Proposal/validator/advancing/successfully advance to failed state: timeout/Draft -> Finished,93571998,246765,5033 +Agora/Proposal/validator/advancing/successfully advance to failed state: timeout/VotingReady -> Finished,92163087,244060,5034 +Agora/Proposal/validator/advancing/successfully advance to failed state: timeout/Locked -> Finished,93294065,246464,5034 Agora/AuthorityToken/singleAuthorityTokenBurned/Correct simple,21017788,55883,806 Agora/AuthorityToken/singleAuthorityTokenBurned/Correct many inputs,33204186,88241,900 Agora/Treasury/Validator/Positive/Allows for effect changes,29938856,79744,1841 Agora/AuthorityToken/singleAuthorityTokenBurned/Correct simple,21017788,55883,806 Agora/AuthorityToken/singleAuthorityTokenBurned/Correct many inputs,33204186,88241,900 Agora/Governor/policy/GST minting,43087287,120125,1833 -Agora/Governor/validator/proposal creation,258936253,681815,8145 -Agora/Governor/validator/GATs minting,358292569,955552,8266 -Agora/Governor/validator/mutate governor state,81661538,223202,7682 +Agora/Governor/validator/proposal creation,261928725,689487,8181 +Agora/Governor/validator/GATs minting,351749811,938560,8302 +Agora/Governor/validator/mutate governor state,81730538,223502,7718 diff --git a/flake.lock b/flake.lock index 3d7df91..bc60c44 100644 --- a/flake.lock +++ b/flake.lock @@ -16,6 +16,22 @@ "type": "github" } }, + "HTTP_10": { + "flake": false, + "locked": { + "lastModified": 1451647621, + "narHash": "sha256-oHIyw3x0iKBexEo49YeUDV1k74ZtyYKGR2gNJXXRxts=", + "owner": "phadej", + "repo": "HTTP", + "rev": "9bc0996d412fef1787449d841277ef663ad9a915", + "type": "github" + }, + "original": { + "owner": "phadej", + "repo": "HTTP", + "type": "github" + } + }, "HTTP_2": { "flake": false, "locked": { @@ -177,6 +193,23 @@ "type": "github" } }, + "cabal-32_10": { + "flake": false, + "locked": { + "lastModified": 1603716527, + "narHash": "sha256-X0TFfdD4KZpwl0Zr6x+PLxUt/VyKQfX7ylXHdmZIL+w=", + "owner": "haskell", + "repo": "cabal", + "rev": "48bf10787e27364730dd37a42b603cee8d6af7ee", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "3.2", + "repo": "cabal", + "type": "github" + } + }, "cabal-32_2": { "flake": false, "locked": { @@ -330,6 +363,23 @@ "type": "github" } }, + "cabal-34_10": { + "flake": false, + "locked": { + "lastModified": 1640353650, + "narHash": "sha256-N1t6M3/wqj90AEdRkeC8i923gQYUpzSr8b40qVOZ1Rk=", + "owner": "haskell", + "repo": "cabal", + "rev": "942639c18c0cd8ec53e0a6f8d120091af35312cd", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "3.4", + "repo": "cabal", + "type": "github" + } + }, "cabal-34_2": { "flake": false, "locked": { @@ -483,6 +533,23 @@ "type": "github" } }, + "cabal-36_10": { + "flake": false, + "locked": { + "lastModified": 1641652457, + "narHash": "sha256-BlFPKP4C4HRUJeAbdembX1Rms1LD380q9s0qVDeoAak=", + "owner": "haskell", + "repo": "cabal", + "rev": "f27667f8ec360c475027dcaee0138c937477b070", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "3.6", + "repo": "cabal", + "type": "github" + } + }, "cabal-36_2": { "flake": false, "locked": { @@ -635,6 +702,22 @@ "type": "github" } }, + "cardano-base_10": { + "flake": false, + "locked": { + "lastModified": 1638456794, + "narHash": "sha256-0KAO6dWqupJzRyjWjAFLZrt0hA6pozeKsDv1Fnysib8=", + "owner": "input-output-hk", + "repo": "cardano-base", + "rev": "4fae3f0149fd8925be94707d3ae0e36c0d67bd58", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "cardano-base", + "type": "github" + } + }, "cardano-base_2": { "flake": false, "locked": { @@ -750,11 +833,11 @@ "cardano-base_9": { "flake": false, "locked": { - "lastModified": 1638456794, - "narHash": "sha256-0KAO6dWqupJzRyjWjAFLZrt0hA6pozeKsDv1Fnysib8=", + "lastModified": 1652788515, + "narHash": "sha256-l0KgomRi6YhEoOlFnBYEXhnZO2+PW68rhfUrbMXjhCQ=", "owner": "input-output-hk", "repo": "cardano-base", - "rev": "4fae3f0149fd8925be94707d3ae0e36c0d67bd58", + "rev": "631cb6cf1fa01ab346233b610a38b3b4cba6e6ab", "type": "github" }, "original": { @@ -780,6 +863,23 @@ "type": "github" } }, + "cardano-crypto_10": { + "flake": false, + "locked": { + "lastModified": 1621376239, + "narHash": "sha256-oxIOVlgm07FAEmgGRF1C2me9TXqVxQulEOcJ22zpTRs=", + "owner": "input-output-hk", + "repo": "cardano-crypto", + "rev": "07397f0e50da97eaa0575d93bee7ac4b2b2576ec", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "cardano-crypto", + "rev": "07397f0e50da97eaa0575d93bee7ac4b2b2576ec", + "type": "github" + } + }, "cardano-crypto_2": { "flake": false, "locked": { @@ -933,6 +1033,23 @@ "type": "github" } }, + "cardano-prelude_10": { + "flake": false, + "locked": { + "lastModified": 1641566029, + "narHash": "sha256-CylaHhO4zbZ1dEAv8yWp1swP1xys/s2Sbxg3a2pdnCI=", + "owner": "locallycompact", + "repo": "cardano-prelude", + "rev": "93f95047bb36a055bdd56fb0cafd887c072cdce2", + "type": "github" + }, + "original": { + "owner": "locallycompact", + "repo": "cardano-prelude", + "rev": "93f95047bb36a055bdd56fb0cafd887c072cdce2", + "type": "github" + } + }, "cardano-prelude_2": { "flake": false, "locked": { @@ -1055,17 +1172,17 @@ "cardano-prelude_9": { "flake": false, "locked": { - "lastModified": 1641566029, - "narHash": "sha256-CylaHhO4zbZ1dEAv8yWp1swP1xys/s2Sbxg3a2pdnCI=", - "owner": "locallycompact", + "lastModified": 1653997332, + "narHash": "sha256-E+YSfUsvxdoOr7n7fz4xd7zb4z8XBRGNYOKipc2A1pw=", + "owner": "mlabs-haskell", "repo": "cardano-prelude", - "rev": "93f95047bb36a055bdd56fb0cafd887c072cdce2", + "rev": "713c7ae79a4d538fcd653c976a652913df1567b9", "type": "github" }, "original": { - "owner": "locallycompact", + "owner": "mlabs-haskell", "repo": "cardano-prelude", - "rev": "93f95047bb36a055bdd56fb0cafd887c072cdce2", + "rev": "713c7ae79a4d538fcd653c976a652913df1567b9", "type": "github" } }, @@ -1085,6 +1202,22 @@ "type": "github" } }, + "cardano-repo-tool_10": { + "flake": false, + "locked": { + "lastModified": 1624584417, + "narHash": "sha256-YSepT97PagR/1jTYV/Yer8a2GjFe9+tTwaTCHxuK50M=", + "owner": "input-output-hk", + "repo": "cardano-repo-tool", + "rev": "30e826ed8f00e3e154453b122a6f3d779b2f73ec", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "cardano-repo-tool", + "type": "github" + } + }, "cardano-repo-tool_2": { "flake": false, "locked": { @@ -1229,6 +1362,22 @@ "type": "github" } }, + "cardano-shell_10": { + "flake": false, + "locked": { + "lastModified": 1608537748, + "narHash": "sha256-PulY1GfiMgKVnBci3ex4ptk2UNYMXqGjJOxcPy2KYT4=", + "owner": "input-output-hk", + "repo": "cardano-shell", + "rev": "9392c75087cb9a3d453998f4230930dea3a95725", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "cardano-shell", + "type": "github" + } + }, "cardano-shell_2": { "flake": false, "locked": { @@ -1525,9 +1674,30 @@ "inputs": { "flake-compat": "flake-compat_15", "flake-utils": "flake-utils_23", - "lint-utils": "lint-utils", "nixpkgs": "nixpkgs_39" }, + "locked": { + "lastModified": 1653742730, + "narHash": "sha256-NyhjoMbm3h1aTskIU6jowNClSgA92bUcGcVNPfWNWgE=", + "owner": "srid", + "repo": "ema", + "rev": "50d9499db16b4e334776d8e8cffcd144c67f9fc4", + "type": "github" + }, + "original": { + "owner": "srid", + "ref": "multisite", + "repo": "ema", + "type": "github" + } + }, + "ema_9": { + "inputs": { + "flake-compat": "flake-compat_17", + "flake-utils": "flake-utils_26", + "lint-utils": "lint-utils", + "nixpkgs": "nixpkgs_44" + }, "locked": { "lastModified": 1650932571, "narHash": "sha256-rdpfJ+10a1uBPtHMNoAcpDE183RzpILRpsMgxj/YJek=", @@ -1818,6 +1988,8 @@ "ema": "ema_7", "flake-compat": [ "plutarch-safe-money", + "liqwid-plutarch-extra", + "plutarch-quickcheck", "plutarch", "emanote", "ema", @@ -1825,6 +1997,8 @@ ], "flake-utils": [ "plutarch-safe-money", + "liqwid-plutarch-extra", + "plutarch-quickcheck", "plutarch", "emanote", "ema", @@ -1834,6 +2008,8 @@ "ixset-typed": "ixset-typed_7", "nixpkgs": [ "plutarch-safe-money", + "liqwid-plutarch-extra", + "plutarch-quickcheck", "plutarch", "emanote", "ema", @@ -1860,6 +2036,50 @@ "emanote_8": { "inputs": { "ema": "ema_8", + "flake-compat": [ + "plutarch-safe-money", + "plutarch", + "emanote", + "ema", + "flake-compat" + ], + "flake-utils": [ + "plutarch-safe-money", + "plutarch", + "emanote", + "ema", + "flake-utils" + ], + "heist": "heist_8", + "ixset-typed": "ixset-typed_8", + "nixpkgs": [ + "plutarch-safe-money", + "plutarch", + "emanote", + "ema", + "nixpkgs" + ], + "pandoc-link-context": "pandoc-link-context_8", + "tailwind-haskell": "tailwind-haskell_8" + }, + "locked": { + "lastModified": 1653742875, + "narHash": "sha256-2IFMkA6/T0nCQHQcC8UhYWh8q8FQyGDBKfcDIhBJ3JM=", + "owner": "srid", + "repo": "emanote", + "rev": "ab5155ef400ce83a744362a4b953315d7ee6a8c3", + "type": "github" + }, + "original": { + "owner": "srid", + "ref": "master", + "repo": "emanote", + "type": "github" + } + }, + "emanote_9": { + "inputs": { + "ema": "ema_9", "flake-compat": [ "plutarch-safe-money", "plutarch-numeric", @@ -1876,8 +2096,8 @@ "ema", "flake-utils" ], - "heist": "heist_8", - "ixset-typed": "ixset-typed_8", + "heist": "heist_9", + "ixset-typed": "ixset-typed_9", "nixpkgs": [ "plutarch-safe-money", "plutarch-numeric", @@ -1886,9 +2106,9 @@ "ema", "nixpkgs" ], - "pandoc-link-context": "pandoc-link-context_8", + "pandoc-link-context": "pandoc-link-context_9", "pathtree": "pathtree", - "tailwind-haskell": "tailwind-haskell_8", + "tailwind-haskell": "tailwind-haskell_9", "unionmount": "unionmount" }, "locked": { @@ -2005,11 +2225,11 @@ "flake-compat_15": { "flake": false, "locked": { - "lastModified": 1648199409, - "narHash": "sha256-JwPKdC2PoVBkG6E+eWw3j6BMR6sL3COpYWfif7RVb8Y=", + "lastModified": 1650374568, + "narHash": "sha256-Z+s0J8/r907g149rllvwhb4pKi8Wam5ij0st8PwAh+E=", "owner": "edolstra", "repo": "flake-compat", - "rev": "64a525ee38886ab9028e6f61790de0832aa3ef03", + "rev": "b4a34015c698c7793d592d66adbab377907a2be8", "type": "github" }, "original": { @@ -2035,6 +2255,22 @@ } }, "flake-compat_17": { + "flake": false, + "locked": { + "lastModified": 1648199409, + "narHash": "sha256-JwPKdC2PoVBkG6E+eWw3j6BMR6sL3COpYWfif7RVb8Y=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "64a525ee38886ab9028e6f61790de0832aa3ef03", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_18": { "flake": false, "locked": { "lastModified": 1641205782, @@ -2050,14 +2286,14 @@ "type": "github" } }, - "flake-compat_18": { + "flake-compat_19": { "flake": false, "locked": { - "lastModified": 1627913399, - "narHash": "sha256-hY8g6H2KFL8ownSiFeMOjwPC8P0ueXpCVEbxgda3pko=", + "lastModified": 1641205782, + "narHash": "sha256-4jY7RCWUoZ9cKD8co0/4tFARpWB+57+r1bLLvXNJliY=", "owner": "edolstra", "repo": "flake-compat", - "rev": "12c64ca55c1014cdc1b16ed5a804aa8576601ff2", + "rev": "b7547d3eed6f32d06102ead8991ec52ab0a4f1a7", "type": "github" }, "original": { @@ -2082,6 +2318,22 @@ "type": "github" } }, + "flake-compat_20": { + "flake": false, + "locked": { + "lastModified": 1627913399, + "narHash": "sha256-hY8g6H2KFL8ownSiFeMOjwPC8P0ueXpCVEbxgda3pko=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "12c64ca55c1014cdc1b16ed5a804aa8576601ff2", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, "flake-compat_3": { "flake": false, "locked": { @@ -2431,20 +2683,37 @@ }, "flake-utils_23": { "locked": { - "lastModified": 1648297722, - "narHash": "sha256-W+qlPsiZd8F3XkzXOzAoR+mpFqzm3ekQkJNa+PIh1BQ=", + "lastModified": 1652776076, + "narHash": "sha256-gzTw/v1vj4dOVbpBSJX4J0DwUR6LIyXo7/SuuTJp1kM=", "owner": "numtide", "repo": "flake-utils", - "rev": "0f8662f1319ad6abf89b3380dd2722369fc51ade", + "rev": "04c1b180862888302ddfb2e3ad9eaa63afc60cf8", "type": "github" }, "original": { "owner": "numtide", + "ref": "v1.0.0", "repo": "flake-utils", "type": "github" } }, "flake-utils_24": { + "locked": { + "lastModified": 1652776076, + "narHash": "sha256-gzTw/v1vj4dOVbpBSJX4J0DwUR6LIyXo7/SuuTJp1kM=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "04c1b180862888302ddfb2e3ad9eaa63afc60cf8", + "type": "github" + }, + "original": { + "owner": "numtide", + "ref": "v1.0.0", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_25": { "locked": { "lastModified": 1644229661, "narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=", @@ -2459,28 +2728,13 @@ "type": "github" } }, - "flake-utils_25": { - "locked": { - "lastModified": 1642700792, - "narHash": "sha256-XqHrk7hFb+zBvRg6Ghl+AZDq03ov6OshJLiSWOoX5es=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "846b2ae0fc4cc943637d3d1def4454213e203cba", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, "flake-utils_26": { "locked": { - "lastModified": 1642700792, - "narHash": "sha256-XqHrk7hFb+zBvRg6Ghl+AZDq03ov6OshJLiSWOoX5es=", + "lastModified": 1648297722, + "narHash": "sha256-W+qlPsiZd8F3XkzXOzAoR+mpFqzm3ekQkJNa+PIh1BQ=", "owner": "numtide", "repo": "flake-utils", - "rev": "846b2ae0fc4cc943637d3d1def4454213e203cba", + "rev": "0f8662f1319ad6abf89b3380dd2722369fc51ade", "type": "github" }, "original": { @@ -2490,6 +2744,66 @@ } }, "flake-utils_27": { + "locked": { + "lastModified": 1644229661, + "narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_28": { + "locked": { + "lastModified": 1642700792, + "narHash": "sha256-XqHrk7hFb+zBvRg6Ghl+AZDq03ov6OshJLiSWOoX5es=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "846b2ae0fc4cc943637d3d1def4454213e203cba", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_29": { + "locked": { + "lastModified": 1642700792, + "narHash": "sha256-XqHrk7hFb+zBvRg6Ghl+AZDq03ov6OshJLiSWOoX5es=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "846b2ae0fc4cc943637d3d1def4454213e203cba", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_3": { + "locked": { + "lastModified": 1644229661, + "narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_30": { "locked": { "lastModified": 1631561581, "narHash": "sha256-3VQMV5zvxaVLvqqUrNz3iJelLw30mIVSfZmAaauM3dA=", @@ -2504,22 +2818,7 @@ "type": "github" } }, - "flake-utils_28": { - "locked": { - "lastModified": 1644229661, - "narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "flake-utils_3": { + "flake-utils_31": { "locked": { "lastModified": 1644229661, "narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=", @@ -2644,6 +2943,23 @@ "type": "github" } }, + "flat_10": { + "flake": false, + "locked": { + "lastModified": 1641898475, + "narHash": "sha256-D7jJ4t0T1ZvXbO61r3HQj77hZ5hWF/P1L8X9+MnfD6c=", + "owner": "Quid2", + "repo": "flat", + "rev": "41a040c413351e021982bb78bd00f750628f8060", + "type": "github" + }, + "original": { + "owner": "Quid2", + "repo": "flat", + "rev": "41a040c413351e021982bb78bd00f750628f8060", + "type": "github" + } + }, "flat_2": { "flake": false, "locked": { @@ -2759,17 +3075,16 @@ "flat_9": { "flake": false, "locked": { - "lastModified": 1641898475, - "narHash": "sha256-D7jJ4t0T1ZvXbO61r3HQj77hZ5hWF/P1L8X9+MnfD6c=", + "lastModified": 1651403785, + "narHash": "sha256-g+jGep1IXdw4q01W67J6f6OODY91QzIlW1+Eu8pR+u0=", "owner": "Quid2", "repo": "flat", - "rev": "41a040c413351e021982bb78bd00f750628f8060", + "rev": "559617e058098b776b431e2a67346ad3adea2440", "type": "github" }, "original": { "owner": "Quid2", "repo": "flat", - "rev": "41a040c413351e021982bb78bd00f750628f8060", "type": "github" } }, @@ -2807,6 +3122,23 @@ "type": "github" } }, + "ghc-8.6.5-iohk_10": { + "flake": false, + "locked": { + "lastModified": 1600920045, + "narHash": "sha256-DO6kxJz248djebZLpSzTGD6s8WRpNI9BTwUeOf5RwY8=", + "owner": "input-output-hk", + "repo": "ghc", + "rev": "95713a6ecce4551240da7c96b6176f980af75cae", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "ref": "release/8.6.5-iohk", + "repo": "ghc", + "type": "github" + } + }, "ghc-8.6.5-iohk_2": { "flake": false, "locked": { @@ -2959,6 +3291,22 @@ "type": "github" } }, + "gitignore-nix_10": { + "flake": false, + "locked": { + "lastModified": 1611672876, + "narHash": "sha256-qHu3uZ/o9jBHiA3MEKHJ06k7w4heOhA+4HCSIvflRxo=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "211907489e9f198594c0eb0ca9256a1949c9d412", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, "gitignore-nix_2": { "flake": false, "locked": { @@ -3119,6 +3467,22 @@ "type": "github" } }, + "hackage-nix_10": { + "flake": false, + "locked": { + "lastModified": 1644369434, + "narHash": "sha256-WqU6f1OhSM0UHXFW8Mhhvhz0tcij+NQVtmb6sW4RiFw=", + "owner": "input-output-hk", + "repo": "hackage.nix", + "rev": "644a0d702abf84cdec62f4e620ff1034000e6146", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "hackage.nix", + "type": "github" + } + }, "hackage-nix_2": { "flake": false, "locked": { @@ -3234,11 +3598,27 @@ "hackage-nix_9": { "flake": false, "locked": { - "lastModified": 1644369434, - "narHash": "sha256-WqU6f1OhSM0UHXFW8Mhhvhz0tcij+NQVtmb6sW4RiFw=", + "lastModified": 1651108473, + "narHash": "sha256-zHGCnBdwKvrcYanjf3GARTWF8V2pyJl1QNONUNZSoc0=", "owner": "input-output-hk", "repo": "hackage.nix", - "rev": "644a0d702abf84cdec62f4e620ff1034000e6146", + "rev": "dbab3b292c3400d028a2257e3acd2ac0249da774", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "hackage.nix", + "type": "github" + } + }, + "hackage_10": { + "flake": false, + "locked": { + "lastModified": 1644887696, + "narHash": "sha256-o4gltv4npUl7+1gEQIcrRqZniwqC9kK8QsPaftlrawc=", + "owner": "input-output-hk", + "repo": "hackage.nix", + "rev": "6ff64aa49b88e75dd6e0bbd2823c2a92c9174fa5", "type": "github" }, "original": { @@ -3362,11 +3742,11 @@ "hackage_9": { "flake": false, "locked": { - "lastModified": 1644887696, - "narHash": "sha256-o4gltv4npUl7+1gEQIcrRqZniwqC9kK8QsPaftlrawc=", + "lastModified": 1654046237, + "narHash": "sha256-FpM9zE+Q+WrvCiaZBCg5U1g0bYpiZOCxY8V3R5ydBu8=", "owner": "input-output-hk", "repo": "hackage.nix", - "rev": "6ff64aa49b88e75dd6e0bbd2823c2a92c9174fa5", + "rev": "eeae1790b9c6a880d96e4a7214fdf0a73bdd6fc0", "type": "github" }, "original": { @@ -3604,6 +3984,22 @@ } }, "haskell-language-server_22": { + "flake": false, + "locked": { + "lastModified": 1654120290, + "narHash": "sha256-6NuFBnEzJPvWfvbYxXk/WCQDjsEbjCQ1nAelhBDi4yQ=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "140f9040ae88352ca1140a750e7c26485fdfbe17", + "type": "github" + }, + "original": { + "owner": "haskell", + "repo": "haskell-language-server", + "type": "github" + } + }, + "haskell-language-server_23": { "flake": false, "locked": { "lastModified": 1653778781, @@ -3619,7 +4015,7 @@ "type": "github" } }, - "haskell-language-server_23": { + "haskell-language-server_24": { "flake": false, "locked": { "lastModified": 1650980856, @@ -3636,7 +4032,56 @@ "type": "github" } }, - "haskell-language-server_24": { + "haskell-language-server_25": { + "flake": false, + "locked": { + "lastModified": 1653778781, + "narHash": "sha256-oEVBaYRLjD4gC3vQuT0DCgmCSIeWSwGPVXXSKJDFUK0=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "8c47d6ce2a8409a285a3f4c3f0e10c25fb4dd848", + "type": "github" + }, + "original": { + "owner": "haskell", + "repo": "haskell-language-server", + "type": "github" + } + }, + "haskell-language-server_26": { + "flake": false, + "locked": { + "lastModified": 1650980856, + "narHash": "sha256-uiwsfh/K3IABZDYj7JUZNIAPRVqH6g/r8X6QKg8DrZE=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "b5a37f7fc360596899cb2945f363030f44156415", + "type": "github" + }, + "original": { + "owner": "haskell", + "ref": "1.7.0.0", + "repo": "haskell-language-server", + "type": "github" + } + }, + "haskell-language-server_27": { + "flake": false, + "locked": { + "lastModified": 1655140576, + "narHash": "sha256-mHJuIk1ElmgPxvEUO2Y3E6T674F2tO5SS/uixf4R2fM=", + "owner": "haskell", + "repo": "haskell-language-server", + "rev": "8a5840a020048c74285f9997b9b02b9b04c658c6", + "type": "github" + }, + "original": { + "owner": "haskell", + "repo": "haskell-language-server", + "type": "github" + } + }, + "haskell-language-server_28": { "flake": false, "locked": { "lastModified": 1645014262, @@ -3652,7 +4097,7 @@ "type": "github" } }, - "haskell-language-server_25": { + "haskell-language-server_29": { "flake": false, "locked": { "lastModified": 1643835246, @@ -4016,6 +4461,37 @@ } }, "haskell-nix-extra-hackage_8": { + "inputs": { + "haskell-nix": [ + "plutarch-safe-money", + "liqwid-plutarch-extra", + "plutarch-quickcheck", + "plutarch", + "haskell-nix" + ], + "nixpkgs": [ + "plutarch-safe-money", + "liqwid-plutarch-extra", + "plutarch-quickcheck", + "plutarch", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1653405678, + "narHash": "sha256-fPpPxuCZDF5b/iQgmUg2jspPObsK0mpcchUti/LR8D0=", + "owner": "mlabs-haskell", + "repo": "haskell-nix-extra-hackage", + "rev": "cf4613eb0d883a8c12c86d7cdbdaaf15fdc70128", + "type": "github" + }, + "original": { + "owner": "mlabs-haskell", + "repo": "haskell-nix-extra-hackage", + "type": "github" + } + }, + "haskell-nix-extra-hackage_9": { "inputs": { "haskell-nix": [ "plutarch-safe-money", @@ -4186,6 +4662,8 @@ "nix-tools": "nix-tools_8", "nixpkgs": [ "plutarch-safe-money", + "liqwid-plutarch-extra", + "plutarch-quickcheck", "plutarch", "haskell-nix", "nixpkgs-unstable" @@ -4234,14 +4712,14 @@ "cabal-34": "cabal-34_9", "cabal-36": "cabal-36_9", "cardano-shell": "cardano-shell_9", - "flake-utils": "flake-utils_28", + "flake-utils": "flake-utils_25", "ghc-8.6.5-iohk": "ghc-8.6.5-iohk_9", "hackage": "hackage_9", "hpc-coveralls": "hpc-coveralls_9", + "hydra": "hydra_9", "nix-tools": "nix-tools_9", "nixpkgs": [ "plutarch-safe-money", - "plutarch-numeric", "plutarch", "haskell-nix", "nixpkgs-unstable" @@ -4253,6 +4731,62 @@ "old-ghc-nix": "old-ghc-nix_9", "stackage": "stackage_9" }, + "locked": { + "lastModified": 1654068838, + "narHash": "sha256-GHSufC21DSg8Lz2AzIg3DA9DPxGvLqxGFa/4ADoXRhU=", + "owner": "input-output-hk", + "repo": "haskell.nix", + "rev": "fa2fa131fe15e630c91ab4078d12eb32c41f934b", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "haskell.nix", + "type": "github" + } + }, + "haskell-nix_18": { + "flake": false, + "locked": { + "lastModified": 1651151636, + "narHash": "sha256-WdMP9IMB5kByT0zimDuCYZF/dinRB104H8iDTG/c1Eo=", + "owner": "input-output-hk", + "repo": "haskell.nix", + "rev": "f707aa2e75c0d33473166abc61c0b43ac6e107c0", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "haskell.nix", + "type": "github" + } + }, + "haskell-nix_19": { + "inputs": { + "HTTP": "HTTP_10", + "cabal-32": "cabal-32_10", + "cabal-34": "cabal-34_10", + "cabal-36": "cabal-36_10", + "cardano-shell": "cardano-shell_10", + "flake-utils": "flake-utils_31", + "ghc-8.6.5-iohk": "ghc-8.6.5-iohk_10", + "hackage": "hackage_10", + "hpc-coveralls": "hpc-coveralls_10", + "nix-tools": "nix-tools_10", + "nixpkgs": [ + "plutarch-safe-money", + "plutarch-numeric", + "plutarch", + "haskell-nix", + "nixpkgs-unstable" + ], + "nixpkgs-2003": "nixpkgs-2003_10", + "nixpkgs-2105": "nixpkgs-2105_10", + "nixpkgs-2111": "nixpkgs-2111_20", + "nixpkgs-unstable": "nixpkgs-unstable_10", + "old-ghc-nix": "old-ghc-nix_10", + "stackage": "stackage_10" + }, "locked": { "lastModified": 1644944726, "narHash": "sha256-jJWdP/3Ne1y1akC3m9rSO5ItRoBc4UTdVQZBCuPmmrM=", @@ -4268,22 +4802,6 @@ "type": "github" } }, - "haskell-nix_18": { - "flake": false, - "locked": { - "lastModified": 1629380841, - "narHash": "sha256-gWOWCfX7IgVSvMMYN6rBGK6EA0pk6pmYguXzMvGte+Q=", - "owner": "input-output-hk", - "repo": "haskell.nix", - "rev": "7215f083b37741446aa325b20c8ba9f9f76015eb", - "type": "github" - }, - "original": { - "owner": "input-output-hk", - "repo": "haskell.nix", - "type": "github" - } - }, "haskell-nix_2": { "flake": false, "locked": { @@ -4300,6 +4818,22 @@ "type": "github" } }, + "haskell-nix_20": { + "flake": false, + "locked": { + "lastModified": 1629380841, + "narHash": "sha256-gWOWCfX7IgVSvMMYN6rBGK6EA0pk6pmYguXzMvGte+Q=", + "owner": "input-output-hk", + "repo": "haskell.nix", + "rev": "7215f083b37741446aa325b20c8ba9f9f76015eb", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "haskell.nix", + "type": "github" + } + }, "haskell-nix_3": { "inputs": { "HTTP": "HTTP_2", @@ -4628,6 +5162,23 @@ } }, "heist_8": { + "flake": false, + "locked": { + "lastModified": 1653169917, + "narHash": "sha256-i52wi4nNC6ATx8gTtmpLnxQZEhKSM0LbpmSu57d5VqI=", + "owner": "srid", + "repo": "heist", + "rev": "75533cade1a0d9859ff487cbf6f22e98711248d3", + "type": "github" + }, + "original": { + "owner": "srid", + "ref": "emanote", + "repo": "heist", + "type": "github" + } + }, + "heist_9": { "flake": false, "locked": { "lastModified": 1649279862, @@ -4662,6 +5213,24 @@ "type": "github" } }, + "hercules-ci-effects_10": { + "inputs": { + "nixpkgs": "nixpkgs_48" + }, + "locked": { + "lastModified": 1647711660, + "narHash": "sha256-ZoV/oAH8g4NYeTzC7OCZnlM7l0hNBs0nUHf4l1+lmDc=", + "owner": "hercules-ci", + "repo": "hercules-ci-effects", + "rev": "d17e41cfb454d07f5d8d3b667bf45b079d868541", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "hercules-ci-effects", + "type": "github" + } + }, "hercules-ci-effects_2": { "inputs": { "nixpkgs": "nixpkgs_9" @@ -4790,14 +5359,14 @@ }, "hercules-ci-effects_9": { "inputs": { - "nixpkgs": "nixpkgs_43" + "nixpkgs": "nixpkgs_42" }, "locked": { - "lastModified": 1647711660, - "narHash": "sha256-ZoV/oAH8g4NYeTzC7OCZnlM7l0hNBs0nUHf4l1+lmDc=", + "lastModified": 1653841712, + "narHash": "sha256-XBF4i1MuIRAEbFpj3Z3fVaYxzNEsYapyENtw3vG+q1I=", "owner": "hercules-ci", "repo": "hercules-ci-effects", - "rev": "d17e41cfb454d07f5d8d3b667bf45b079d868541", + "rev": "e14d2131b7c81acca3904b584ac45fb72da64dd2", "type": "github" }, "original": { @@ -4822,6 +5391,22 @@ "type": "github" } }, + "hpc-coveralls_10": { + "flake": false, + "locked": { + "lastModified": 1607498076, + "narHash": "sha256-8uqsEtivphgZWYeUo5RDUhp6bO9j2vaaProQxHBltQk=", + "owner": "sevanspowell", + "repo": "hpc-coveralls", + "rev": "14df0f7d229f4cd2e79f8eabb1a740097fdfa430", + "type": "github" + }, + "original": { + "owner": "sevanspowell", + "repo": "hpc-coveralls", + "type": "github" + } + }, "hpc-coveralls_2": { "flake": false, "locked": { @@ -5195,6 +5780,33 @@ "hydra_8": { "inputs": { "nix": "nix_8", + "nixpkgs": [ + "plutarch-safe-money", + "liqwid-plutarch-extra", + "plutarch-quickcheck", + "plutarch", + "haskell-nix", + "hydra", + "nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1646878427, + "narHash": "sha256-KtbrofMtN8GlM7D+n90kixr7QpSlVmdN+vK5CA/aRzc=", + "owner": "NixOS", + "repo": "hydra", + "rev": "28b682b85b7efc5cf7974065792a1f22203a5927", + "type": "github" + }, + "original": { + "id": "hydra", + "type": "indirect" + } + }, + "hydra_9": { + "inputs": { + "nix": "nix_9", "nixpkgs": [ "plutarch-safe-money", "plutarch", @@ -5348,11 +5960,11 @@ "iohk-nix_17": { "flake": false, "locked": { - "lastModified": 1643251385, - "narHash": "sha256-Czbd69lg0ARSZfC18V6h+gtPMioWDAEVPbiHgL2x9LM=", + "lastModified": 1653579289, + "narHash": "sha256-wveDdPsgB/3nAGAdFaxrcgLEpdi0aJ5kEVNtI+YqVfo=", "owner": "input-output-hk", "repo": "iohk-nix", - "rev": "9d6ee3dcb3482f791e40ed991ad6fc649b343ad4", + "rev": "edb2d2df2ebe42bbdf03a0711115cf6213c9d366", "type": "github" }, "original": { @@ -5377,6 +5989,22 @@ "type": "github" } }, + "iohk-nix_19": { + "flake": false, + "locked": { + "lastModified": 1643251385, + "narHash": "sha256-Czbd69lg0ARSZfC18V6h+gtPMioWDAEVPbiHgL2x9LM=", + "owner": "input-output-hk", + "repo": "iohk-nix", + "rev": "9d6ee3dcb3482f791e40ed991ad6fc649b343ad4", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "iohk-nix", + "type": "github" + } + }, "iohk-nix_2": { "flake": false, "locked": { @@ -5393,6 +6021,22 @@ "type": "github" } }, + "iohk-nix_20": { + "flake": false, + "locked": { + "lastModified": 1626953580, + "narHash": "sha256-iEI9aTOaZMGsjWzcrctrC0usmiagwKT2v1LSDe9/tMU=", + "owner": "input-output-hk", + "repo": "iohk-nix", + "rev": "cbd497f5844249ef8fe617166337d59f2a6ebe90", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "iohk-nix", + "type": "github" + } + }, "iohk-nix_3": { "flake": false, "locked": { @@ -5618,6 +6262,22 @@ } }, "ixset-typed_8": { + "flake": false, + "locked": { + "lastModified": 1652177108, + "narHash": "sha256-g0N1jiumsxHzfo9SGVR+q9awRvHEehSRaoW89LXCCnY=", + "owner": "well-typed", + "repo": "ixset-typed", + "rev": "244d3b72fd051b8d78f2d4edb6208269f29d85b7", + "type": "github" + }, + "original": { + "owner": "well-typed", + "repo": "ixset-typed", + "type": "github" + } + }, + "ixset-typed_9": { "flake": false, "locked": { "lastModified": 1639657838, @@ -5635,7 +6295,7 @@ }, "lint-utils": { "inputs": { - "flake-utils": "flake-utils_24", + "flake-utils": "flake-utils_27", "nixpkgs": [ "plutarch-safe-money", "plutarch-numeric", @@ -5679,11 +6339,11 @@ "plutarch-quickcheck": "plutarch-quickcheck" }, "locked": { - "lastModified": 1654960547, - "narHash": "sha256-Zi0WDUh/aH8a64EHNv7QHK1cbKM6q0GcrRKOqso5lSA=", + "lastModified": 1655470312, + "narHash": "sha256-O4Dy803SFOS+S1OFEecfCRkjWc8y0iHbO+EVKtBqsGk=", "owner": "Liqwid-Labs", "repo": "liqwid-plutarch-extra", - "rev": "6293833a8ea885c34fbde157d5d69bd8da3bdd76", + "rev": "fd9b2e6e713c36efef30bcef8d97a069fda7d71a", "type": "github" }, "original": { @@ -5710,21 +6370,22 @@ ], "nixpkgs-2111": "nixpkgs-2111_13", "nixpkgs-latest": "nixpkgs-latest_13", - "plutarch": "plutarch_7" + "plutarch": "plutarch_7", + "plutarch-quickcheck": "plutarch-quickcheck_3" }, "locked": { - "lastModified": 1654189693, - "narHash": "sha256-rBMKRsAn+T8nvPY5T1U3MZ+yxM54OOECXcoeZ/gKjyE=", - "ref": "main", - "rev": "e147c95d8698502d1078ad612ad18affafcba3ba", - "revCount": 18, - "type": "git", - "url": "ssh://git@github.com/Liqwid-Labs/liqwid-plutarch-extra" + "lastModified": 1655470312, + "narHash": "sha256-O4Dy803SFOS+S1OFEecfCRkjWc8y0iHbO+EVKtBqsGk=", + "owner": "Liqwid-Labs", + "repo": "liqwid-plutarch-extra", + "rev": "fd9b2e6e713c36efef30bcef8d97a069fda7d71a", + "type": "github" }, "original": { + "owner": "Liqwid-Labs", "ref": "main", - "type": "git", - "url": "ssh://git@github.com/Liqwid-Labs/liqwid-plutarch-extra" + "repo": "liqwid-plutarch-extra", + "type": "github" } }, "lowdown-src": { @@ -5855,6 +6516,22 @@ "type": "github" } }, + "lowdown-src_9": { + "flake": false, + "locked": { + "lastModified": 1633514407, + "narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=", + "owner": "kristapsdz", + "repo": "lowdown", + "rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8", + "type": "github" + }, + "original": { + "owner": "kristapsdz", + "repo": "lowdown", + "type": "github" + } + }, "nix": { "inputs": { "lowdown-src": "lowdown-src", @@ -5892,6 +6569,22 @@ "type": "github" } }, + "nix-tools_10": { + "flake": false, + "locked": { + "lastModified": 1644395812, + "narHash": "sha256-BVFk/BEsTLq5MMZvdy3ZYHKfaS3dHrsKh4+tb5t5b58=", + "owner": "input-output-hk", + "repo": "nix-tools", + "rev": "d847c63b99bbec78bf83be2a61dc9f09b8a9ccc1", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "nix-tools", + "type": "github" + } + }, "nix-tools_2": { "flake": false, "locked": { @@ -6007,11 +6700,11 @@ "nix-tools_9": { "flake": false, "locked": { - "lastModified": 1644395812, - "narHash": "sha256-BVFk/BEsTLq5MMZvdy3ZYHKfaS3dHrsKh4+tb5t5b58=", + "lastModified": 1649424170, + "narHash": "sha256-XgKXWispvv5RCvZzPb+p7e6Hy3LMuRjafKMl7kXzxGw=", "owner": "input-output-hk", "repo": "nix-tools", - "rev": "d847c63b99bbec78bf83be2a61dc9f09b8a9ccc1", + "rev": "e109c94016e3b6e0db7ed413c793e2d4bdb24aa7", "type": "github" }, "original": { @@ -6167,6 +6860,27 @@ "type": "github" } }, + "nix_9": { + "inputs": { + "lowdown-src": "lowdown-src_9", + "nixpkgs": "nixpkgs_41", + "nixpkgs-regression": "nixpkgs-regression_9" + }, + "locked": { + "lastModified": 1643066034, + "narHash": "sha256-xEPeMcNJVOeZtoN+d+aRwolpW8mFSEQx76HTRdlhPhg=", + "owner": "NixOS", + "repo": "nix", + "rev": "a1cd7e58606a41fcf62bf8637804cf8306f17f62", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "2.6.0", + "repo": "nix", + "type": "github" + } + }, "nixpkgs": { "locked": { "lastModified": 1652885393, @@ -6199,6 +6913,22 @@ "type": "github" } }, + "nixpkgs-2003_10": { + "locked": { + "lastModified": 1620055814, + "narHash": "sha256-8LEHoYSJiL901bTMVatq+rf8y7QtWuZhwwpKE2fyaRY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "1db42b7fe3878f3f5f7a4f2dc210772fd080e205", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-20.03-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, "nixpkgs-2003_2": { "locked": { "lastModified": 1620055814, @@ -6343,6 +7073,22 @@ "type": "github" } }, + "nixpkgs-2105_10": { + "locked": { + "lastModified": 1642244250, + "narHash": "sha256-vWpUEqQdVP4srj+/YLJRTN9vjpTs4je0cdWKXPbDItc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "0fd9ee1aa36ce865ad273f4f07fdc093adeb5c00", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-21.05-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, "nixpkgs-2105_2": { "locked": { "lastModified": 1645296114, @@ -6457,11 +7203,11 @@ }, "nixpkgs-2105_9": { "locked": { - "lastModified": 1642244250, - "narHash": "sha256-vWpUEqQdVP4srj+/YLJRTN9vjpTs4je0cdWKXPbDItc=", + "lastModified": 1645296114, + "narHash": "sha256-y53N7TyIkXsjMpOG7RhvqJFGDacLs9HlyHeSTBioqYU=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "0fd9ee1aa36ce865ad273f4f07fdc093adeb5c00", + "rev": "530a53dcbc9437363471167a5e4762c5fcfa34a1", "type": "github" }, "original": { @@ -6569,11 +7315,11 @@ }, "nixpkgs-2111_15": { "locked": { - "lastModified": 1653319070, - "narHash": "sha256-Z3cv967iN6mXgxhq1cjOoPod23XgNttCWHXMnMZUq9E=", + "lastModified": 1652364845, + "narHash": "sha256-1pG2GR+z7IrUVGcMoTsH6nJ+ACMvBplo/Pyw4SXJDIE=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "1c813bbdc330b45fe922c642eb610902aecd5673", + "rev": "ee80943d4d1160f460e3d719222212dbfbc6a193", "type": "github" }, "original": { @@ -6617,11 +7363,27 @@ }, "nixpkgs-2111_18": { "locked": { - "lastModified": 1644510859, - "narHash": "sha256-xjpVvL5ecbyi0vxtVl/Fh9bwGlMbw3S06zE5nUzFB8A=", + "lastModified": 1648744337, + "narHash": "sha256-bYe1dFJAXovjqiaPKrmAbSBEK5KUkgwVaZcTbSoJ7hg=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "0d1d5d7e3679fec9d07f2eb804d9f9fdb98378d3", + "rev": "0a58eebd8ec65ffdef2ce9562784123a73922052", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-21.11-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2111_19": { + "locked": { + "lastModified": 1653319070, + "narHash": "sha256-Z3cv967iN6mXgxhq1cjOoPod23XgNttCWHXMnMZUq9E=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "1c813bbdc330b45fe922c642eb610902aecd5673", "type": "github" }, "original": { @@ -6647,6 +7409,22 @@ "type": "github" } }, + "nixpkgs-2111_20": { + "locked": { + "lastModified": 1644510859, + "narHash": "sha256-xjpVvL5ecbyi0vxtVl/Fh9bwGlMbw3S06zE5nUzFB8A=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "0d1d5d7e3679fec9d07f2eb804d9f9fdb98378d3", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-21.11-darwin", + "repo": "nixpkgs", + "type": "github" + } + }, "nixpkgs-2111_3": { "locked": { "lastModified": 1652364845, @@ -6887,6 +7665,54 @@ "type": "github" } }, + "nixpkgs-latest_17": { + "locked": { + "lastModified": 1653918805, + "narHash": "sha256-6ahwAnBNGgqSNSn/6RnsxrlFi+fkA+RyT6o/5S1915o=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a0a69be4b5ee63f1b5e75887a406e9194012b492", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a0a69be4b5ee63f1b5e75887a406e9194012b492", + "type": "github" + } + }, + "nixpkgs-latest_18": { + "locked": { + "lastModified": 1653918805, + "narHash": "sha256-6ahwAnBNGgqSNSn/6RnsxrlFi+fkA+RyT6o/5S1915o=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a0a69be4b5ee63f1b5e75887a406e9194012b492", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a0a69be4b5ee63f1b5e75887a406e9194012b492", + "type": "github" + } + }, + "nixpkgs-latest_19": { + "locked": { + "lastModified": 1653918805, + "narHash": "sha256-6ahwAnBNGgqSNSn/6RnsxrlFi+fkA+RyT6o/5S1915o=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a0a69be4b5ee63f1b5e75887a406e9194012b492", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a0a69be4b5ee63f1b5e75887a406e9194012b492", + "type": "github" + } + }, "nixpkgs-latest_2": { "locked": { "lastModified": 1653918805, @@ -7135,6 +7961,21 @@ "type": "indirect" } }, + "nixpkgs-regression_9": { + "locked": { + "lastModified": 1643052045, + "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "indirect" + } + }, "nixpkgs-unstable": { "locked": { "lastModified": 1648219316, @@ -7151,6 +7992,22 @@ "type": "github" } }, + "nixpkgs-unstable_10": { + "locked": { + "lastModified": 1644486793, + "narHash": "sha256-EeijR4guVHgVv+JpOX3cQO+1XdrkJfGmiJ9XVsVU530=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "1882c6b7368fd284ad01b0a5b5601ef136321292", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, "nixpkgs-unstable_2": { "locked": { "lastModified": 1648219316, @@ -7265,11 +8122,11 @@ }, "nixpkgs-unstable_9": { "locked": { - "lastModified": 1644486793, - "narHash": "sha256-EeijR4guVHgVv+JpOX3cQO+1XdrkJfGmiJ9XVsVU530=", + "lastModified": 1648219316, + "narHash": "sha256-Ctij+dOi0ZZIfX5eMhgwugfvB+WZSrvVNAyAuANOsnQ=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "1882c6b7368fd284ad01b0a5b5601ef136321292", + "rev": "30d3d79b7d3607d56546dd2a6b49e156ba0ec634", "type": "github" }, "original": { @@ -7765,17 +8622,17 @@ }, "nixpkgs_39": { "locked": { - "lastModified": 1650882267, - "narHash": "sha256-BFKiz8srATQIBuFEN2HgS2EHisK29EjZ/HV34wSr2lU=", + "lastModified": 1652885393, + "narHash": "sha256-YIgvvlk4iQ1Hi7KD9o5gsojc+ApB+jiH1d5stK8uXiw=", "owner": "nixos", "repo": "nixpkgs", - "rev": "2ea2f7b6d0cb7ce0712f2aa80303cda08deb0de2", + "rev": "48037fd90426e44e4bf03e6479e88a11453b9b66", "type": "github" }, "original": { "owner": "nixos", + "ref": "nixos-unstable", "repo": "nixpkgs", - "rev": "2ea2f7b6d0cb7ce0712f2aa80303cda08deb0de2", "type": "github" } }, @@ -7797,43 +8654,11 @@ }, "nixpkgs_40": { "locked": { - "lastModified": 1647350163, - "narHash": "sha256-OcMI+PFEHTONthXuEQNddt16Ml7qGvanL3x8QOl2Aao=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "3eb07eeafb52bcbf02ce800f032f18d666a9498d", - "type": "github" - }, - "original": { - "owner": "nixos", - "repo": "nixpkgs", - "rev": "3eb07eeafb52bcbf02ce800f032f18d666a9498d", - "type": "github" - } - }, - "nixpkgs_41": { - "locked": { - "lastModified": 1649456639, - "narHash": "sha256-rZCjaEAZgOtT9kYTBigksof64SqKAXOuoHhlzHvfl0E=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "c48167590e3258daac6ab12a41bc2b7341e9b2ec", - "type": "github" - }, - "original": { - "owner": "nixos", - "repo": "nixpkgs", - "rev": "c48167590e3258daac6ab12a41bc2b7341e9b2ec", - "type": "github" - } - }, - "nixpkgs_42": { - "locked": { - "lastModified": 1648219316, - "narHash": "sha256-Ctij+dOi0ZZIfX5eMhgwugfvB+WZSrvVNAyAuANOsnQ=", + "lastModified": 1653117584, + "narHash": "sha256-5uUrHeHBIaySBTrRExcCoW8fBBYVSDjDYDU5A6iOl+k=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "30d3d79b7d3607d56546dd2a6b49e156ba0ec634", + "rev": "f4dfed73ee886b115a99e5b85fdfbeb683290d83", "type": "github" }, "original": { @@ -7841,7 +8666,22 @@ "type": "indirect" } }, - "nixpkgs_43": { + "nixpkgs_41": { + "locked": { + "lastModified": 1632864508, + "narHash": "sha256-d127FIvGR41XbVRDPVvozUPQ/uRHbHwvfyKHwEt5xFM=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "82891b5e2c2359d7e58d08849e4c89511ab94234", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-21.05-small", + "type": "indirect" + } + }, + "nixpkgs_42": { "locked": { "lastModified": 1647297614, "narHash": "sha256-ulGq3W5XsrBMU/u5k9d4oPy65pQTkunR4HKKtTq0RwY=", @@ -7857,7 +8697,102 @@ "type": "github" } }, + "nixpkgs_43": { + "flake": false, + "locked": { + "lastModified": 1645493675, + "narHash": "sha256-9xundbZQbhFodsQRh6QMN1GeSXfo3y/5NL0CZcJULz0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "74b10859829153d5c5d50f7c77b86763759e8654", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, "nixpkgs_44": { + "locked": { + "lastModified": 1650882267, + "narHash": "sha256-BFKiz8srATQIBuFEN2HgS2EHisK29EjZ/HV34wSr2lU=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "2ea2f7b6d0cb7ce0712f2aa80303cda08deb0de2", + "type": "github" + }, + "original": { + "owner": "nixos", + "repo": "nixpkgs", + "rev": "2ea2f7b6d0cb7ce0712f2aa80303cda08deb0de2", + "type": "github" + } + }, + "nixpkgs_45": { + "locked": { + "lastModified": 1647350163, + "narHash": "sha256-OcMI+PFEHTONthXuEQNddt16Ml7qGvanL3x8QOl2Aao=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "3eb07eeafb52bcbf02ce800f032f18d666a9498d", + "type": "github" + }, + "original": { + "owner": "nixos", + "repo": "nixpkgs", + "rev": "3eb07eeafb52bcbf02ce800f032f18d666a9498d", + "type": "github" + } + }, + "nixpkgs_46": { + "locked": { + "lastModified": 1649456639, + "narHash": "sha256-rZCjaEAZgOtT9kYTBigksof64SqKAXOuoHhlzHvfl0E=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "c48167590e3258daac6ab12a41bc2b7341e9b2ec", + "type": "github" + }, + "original": { + "owner": "nixos", + "repo": "nixpkgs", + "rev": "c48167590e3258daac6ab12a41bc2b7341e9b2ec", + "type": "github" + } + }, + "nixpkgs_47": { + "locked": { + "lastModified": 1648219316, + "narHash": "sha256-Ctij+dOi0ZZIfX5eMhgwugfvB+WZSrvVNAyAuANOsnQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "30d3d79b7d3607d56546dd2a6b49e156ba0ec634", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "nixpkgs_48": { + "locked": { + "lastModified": 1647297614, + "narHash": "sha256-ulGq3W5XsrBMU/u5k9d4oPy65pQTkunR4HKKtTq0RwY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "73ad5f9e147c0d2a2061f1d4bd91e05078dc0b58", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_49": { "flake": false, "locked": { "lastModified": 1628785280, @@ -7969,6 +8904,23 @@ "type": "github" } }, + "old-ghc-nix_10": { + "flake": false, + "locked": { + "lastModified": 1631092763, + "narHash": "sha256-sIKgO+z7tj4lw3u6oBZxqIhDrzSkvpHtv0Kki+lh9Fg=", + "owner": "angerman", + "repo": "old-ghc-nix", + "rev": "af48a7a7353e418119b6dfe3cd1463a657f342b8", + "type": "github" + }, + "original": { + "owner": "angerman", + "ref": "master", + "repo": "old-ghc-nix", + "type": "github" + } + }, "old-ghc-nix_2": { "flake": false, "locked": { @@ -8225,6 +9177,23 @@ } }, "pandoc-link-context_8": { + "flake": false, + "locked": { + "lastModified": 1653170888, + "narHash": "sha256-bA/Oj2pt3H2b4lqWqVBYo3Qhvhd01r4vM39+vLuPMtA=", + "owner": "srid", + "repo": "pandoc-link-context", + "rev": "c3a3de34b291b2bfec04387af65e0cc0822373c5", + "type": "github" + }, + "original": { + "owner": "srid", + "ref": "master", + "repo": "pandoc-link-context", + "type": "github" + } + }, + "pandoc-link-context_9": { "flake": false, "locked": { "lastModified": 1650932770, @@ -8243,9 +9212,9 @@ }, "pathtree": { "inputs": { - "flake-compat": "flake-compat_16", - "flake-utils": "flake-utils_25", - "nixpkgs": "nixpkgs_40" + "flake-compat": "flake-compat_18", + "flake-utils": "flake-utils_28", + "nixpkgs": "nixpkgs_45" }, "locked": { "lastModified": 1649011952, @@ -8365,6 +9334,7 @@ }, "plutarch-numeric_2": { "inputs": { + "haskell-language-server": "haskell-language-server_27", "haskell-nix": [ "plutarch-safe-money", "plutarch-numeric", @@ -8377,22 +9347,23 @@ "plutarch", "nixpkgs" ], - "nixpkgs-2111": "nixpkgs-2111_17", - "plutarch": "plutarch_9" + "nixpkgs-2111": "nixpkgs-2111_19", + "nixpkgs-latest": "nixpkgs-latest_19", + "plutarch": "plutarch_10" }, "locked": { - "lastModified": 1653523611, - "narHash": "sha256-Qt5tFw8NCkMo+QLuRrM07cZ6qZHDbKHEtfCFJdBBZGw=", - "ref": "main", - "rev": "5bccbdd1d4b6cdb000e40f7ab5ea3937e0384477", - "revCount": 2, - "type": "git", - "url": "ssh://git@github.com/Liqwid-Labs/plutarch-numeric" + "lastModified": 1654950823, + "narHash": "sha256-fq6Iyk1ygNs4sTS55jLjx0hWFAFQNKXBGrVHuzRXFls=", + "owner": "Liqwid-Labs", + "repo": "plutarch-numeric", + "rev": "11fdf47fdcbf19d51ed587b0b67618152098f442", + "type": "github" }, "original": { + "owner": "Liqwid-Labs", "ref": "main", - "type": "git", - "url": "ssh://git@github.com/Liqwid-Labs/plutarch-numeric" + "repo": "plutarch-numeric", + "type": "github" } }, "plutarch-quickcheck": { @@ -8415,17 +9386,17 @@ "plutarch": "plutarch_2" }, "locked": { - "lastModified": 1654293728, - "narHash": "sha256-6Pd410I03CetLM4YYrJmMldOYDyqGPATlmorhKKWU0Q=", + "lastModified": 1655113586, + "narHash": "sha256-hv9tzB3IGvga6/SBDnk16S3Sfp03tvtkWd8COW0It30=", "owner": "liqwid-labs", "repo": "plutarch-quickcheck", - "rev": "cd7df08176e0ee5111980ead903764979d920147", + "rev": "a560e12b4809c0f292c96e81189e1b2cf2e7f7eb", "type": "github" }, "original": { "owner": "liqwid-labs", - "ref": "staging", "repo": "plutarch-quickcheck", + "rev": "a560e12b4809c0f292c96e81189e1b2cf2e7f7eb", "type": "github" } }, @@ -8461,6 +9432,42 @@ "type": "github" } }, + "plutarch-quickcheck_3": { + "inputs": { + "haskell-language-server": "haskell-language-server_22", + "haskell-nix": [ + "plutarch-safe-money", + "liqwid-plutarch-extra", + "plutarch-quickcheck", + "plutarch", + "haskell-nix" + ], + "nixpkgs": [ + "plutarch-safe-money", + "liqwid-plutarch-extra", + "plutarch-quickcheck", + "plutarch", + "nixpkgs" + ], + "nixpkgs-2111": "nixpkgs-2111_15", + "nixpkgs-latest": "nixpkgs-latest_15", + "plutarch": "plutarch_8" + }, + "locked": { + "lastModified": 1655113586, + "narHash": "sha256-hv9tzB3IGvga6/SBDnk16S3Sfp03tvtkWd8COW0It30=", + "owner": "liqwid-labs", + "repo": "plutarch-quickcheck", + "rev": "a560e12b4809c0f292c96e81189e1b2cf2e7f7eb", + "type": "github" + }, + "original": { + "owner": "liqwid-labs", + "repo": "plutarch-quickcheck", + "rev": "a560e12b4809c0f292c96e81189e1b2cf2e7f7eb", + "type": "github" + } + }, "plutarch-safe-money": { "inputs": { "haskell-language-server": "haskell-language-server_18", @@ -8475,23 +9482,68 @@ "plutarch", "nixpkgs" ], - "nixpkgs-2111": "nixpkgs-2111_15", - "nixpkgs-latest": "nixpkgs-latest_15", - "plutarch": "plutarch_8", + "nixpkgs-2111": "nixpkgs-2111_17", + "nixpkgs-latest": "nixpkgs-latest_17", + "plutarch": "plutarch_9", "plutarch-numeric": "plutarch-numeric_2" }, "locked": { - "lastModified": 1654950744, - "narHash": "sha256-WqPzU5+Vi4Ei7d2izbO1Krs8Pa5ZFwypmpdFrTapUy4=", + "lastModified": 1655471113, + "narHash": "sha256-6z17r2rs2M+Gv7MJep6+zP2bq6G5Id4XDhInpU5RulM=", "owner": "Liqwid-Labs", "repo": "plutarch-safe-money", - "rev": "f0316955004aaec38c424b922b09267cf9cf76d7", + "rev": "9f968b80189c7e4b335527cd5b103dc26952f667", "type": "github" }, "original": { "owner": "Liqwid-Labs", - "ref": "main", "repo": "plutarch-safe-money", + "rev": "9f968b80189c7e4b335527cd5b103dc26952f667", + "type": "github" + } + }, + "plutarch_10": { + "inputs": { + "Shrinker": "Shrinker", + "cardano-base": "cardano-base_10", + "cardano-crypto": "cardano-crypto_10", + "cardano-prelude": "cardano-prelude_10", + "cryptonite": "cryptonite", + "emanote": "emanote_9", + "flat": "flat_10", + "foundation": "foundation", + "haskell-language-server": "haskell-language-server_28", + "haskell-nix": "haskell-nix_19", + "hercules-ci-effects": "hercules-ci-effects_10", + "hs-memory": "hs-memory", + "hspec": "hspec", + "hspec-golden": "hspec-golden", + "hspec-hedgehog": "hspec-hedgehog", + "iohk-nix": "iohk-nix_19", + "nixpkgs": [ + "plutarch-safe-money", + "plutarch-numeric", + "plutarch", + "haskell-nix", + "nixpkgs-unstable" + ], + "plutus": "plutus_10", + "protolude": "protolude_10", + "sized-functors": "sized-functors", + "th-extras": "th-extras" + }, + "locked": { + "lastModified": 1652353304, + "narHash": "sha256-DeSwiDyJeI9had5OCxLiGtYeDl07Vic0cR8RETBLY9k=", + "owner": "Liqwid-Labs", + "repo": "plutarch", + "rev": "ae2059f11f24d47bedeaa18749d01711cddab0bc", + "type": "github" + }, + "original": { + "owner": "Liqwid-Labs", + "ref": "staging", + "repo": "plutarch", "type": "github" } }, @@ -8735,13 +9787,15 @@ "cardano-prelude": "cardano-prelude_8", "emanote": "emanote_7", "flat": "flat_8", - "haskell-language-server": "haskell-language-server_22", + "haskell-language-server": "haskell-language-server_23", "haskell-nix": "haskell-nix_15", "haskell-nix-extra-hackage": "haskell-nix-extra-hackage_8", "hercules-ci-effects": "hercules-ci-effects_8", "iohk-nix": "iohk-nix_15", "nixpkgs": [ "plutarch-safe-money", + "liqwid-plutarch-extra", + "plutarch-quickcheck", "plutarch", "haskell-nix", "nixpkgs-unstable" @@ -8768,40 +9822,33 @@ }, "plutarch_9": { "inputs": { - "Shrinker": "Shrinker", "cardano-base": "cardano-base_9", "cardano-crypto": "cardano-crypto_9", "cardano-prelude": "cardano-prelude_9", - "cryptonite": "cryptonite", "emanote": "emanote_8", "flat": "flat_9", - "foundation": "foundation", - "haskell-language-server": "haskell-language-server_24", + "haskell-language-server": "haskell-language-server_25", "haskell-nix": "haskell-nix_17", + "haskell-nix-extra-hackage": "haskell-nix-extra-hackage_9", "hercules-ci-effects": "hercules-ci-effects_9", - "hs-memory": "hs-memory", - "hspec": "hspec", - "hspec-golden": "hspec-golden", - "hspec-hedgehog": "hspec-hedgehog", "iohk-nix": "iohk-nix_17", "nixpkgs": [ "plutarch-safe-money", - "plutarch-numeric", "plutarch", "haskell-nix", "nixpkgs-unstable" ], + "nixpkgs-latest": "nixpkgs-latest_18", "plutus": "plutus_9", "protolude": "protolude_9", - "sized-functors": "sized-functors", - "th-extras": "th-extras" + "secp256k1-haskell": "secp256k1-haskell_9" }, "locked": { - "lastModified": 1652353304, - "narHash": "sha256-DeSwiDyJeI9had5OCxLiGtYeDl07Vic0cR8RETBLY9k=", + "lastModified": 1654108284, + "narHash": "sha256-VD0zX4pFrJJaaUO7uJgioZGg1moe1Fy8nAb5j2mV/Qc=", "owner": "Liqwid-Labs", "repo": "plutarch", - "rev": "ae2059f11f24d47bedeaa18749d01711cddab0bc", + "rev": "e7ef565645146e26e75ec29fe97122a74e52c6b7", "type": "github" }, "original": { @@ -8837,6 +9884,34 @@ "type": "github" } }, + "plutus_10": { + "inputs": { + "cardano-repo-tool": "cardano-repo-tool_10", + "gitignore-nix": "gitignore-nix_10", + "hackage-nix": "hackage-nix_10", + "haskell-language-server": "haskell-language-server_29", + "haskell-nix": "haskell-nix_20", + "iohk-nix": "iohk-nix_20", + "nixpkgs": "nixpkgs_49", + "pre-commit-hooks-nix": "pre-commit-hooks-nix_10", + "sphinxcontrib-haddock": "sphinxcontrib-haddock_10", + "stackage-nix": "stackage-nix" + }, + "locked": { + "lastModified": 1645203653, + "narHash": "sha256-HAi60mSkyMXzu1Wg3h6KdYZg+ufNMvX6obfcLo0ArL0=", + "owner": "L-as", + "repo": "plutus", + "rev": "5ec17953aae3ac9546f6d923201eb1dbb4e058bb", + "type": "github" + }, + "original": { + "owner": "L-as", + "ref": "ghc9", + "repo": "plutus", + "type": "github" + } + }, "plutus_2": { "inputs": { "cardano-repo-tool": "cardano-repo-tool_2", @@ -8998,7 +10073,7 @@ "cardano-repo-tool": "cardano-repo-tool_8", "gitignore-nix": "gitignore-nix_8", "hackage-nix": "hackage-nix_8", - "haskell-language-server": "haskell-language-server_23", + "haskell-language-server": "haskell-language-server_24", "haskell-nix": "haskell-nix_16", "iohk-nix": "iohk-nix_16", "nixpkgs": "nixpkgs_38", @@ -9024,25 +10099,23 @@ "cardano-repo-tool": "cardano-repo-tool_9", "gitignore-nix": "gitignore-nix_9", "hackage-nix": "hackage-nix_9", - "haskell-language-server": "haskell-language-server_25", + "haskell-language-server": "haskell-language-server_26", "haskell-nix": "haskell-nix_18", "iohk-nix": "iohk-nix_18", - "nixpkgs": "nixpkgs_44", + "nixpkgs": "nixpkgs_43", "pre-commit-hooks-nix": "pre-commit-hooks-nix_9", - "sphinxcontrib-haddock": "sphinxcontrib-haddock_9", - "stackage-nix": "stackage-nix" + "sphinxcontrib-haddock": "sphinxcontrib-haddock_9" }, "locked": { - "lastModified": 1645203653, - "narHash": "sha256-HAi60mSkyMXzu1Wg3h6KdYZg+ufNMvX6obfcLo0ArL0=", - "owner": "L-as", + "lastModified": 1653669501, + "narHash": "sha256-qJrjEeo9Jmar1TwihDFzKQNC1ui4M03iClJM1zMd5Uk=", + "owner": "input-output-hk", "repo": "plutus", - "rev": "5ec17953aae3ac9546f6d923201eb1dbb4e058bb", + "rev": "fed48a71550a12290efc84eefb74305d93cde69d", "type": "github" }, "original": { - "owner": "L-as", - "ref": "ghc9", + "owner": "input-output-hk", "repo": "plutus", "type": "github" } @@ -9063,6 +10136,22 @@ "type": "github" } }, + "pre-commit-hooks-nix_10": { + "flake": false, + "locked": { + "lastModified": 1624971177, + "narHash": "sha256-Amf/nBj1E77RmbSSmV+hg6YOpR+rddCbbVgo5C7BS0I=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "397f0713d007250a2c7a745e555fa16c5dc8cadb", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, "pre-commit-hooks-nix_2": { "flake": false, "locked": { @@ -9207,6 +10296,23 @@ "type": "github" } }, + "protolude_10": { + "flake": false, + "locked": { + "lastModified": 1637276813, + "narHash": "sha256-/mgR1Vyp1WYBjdkbwQycrf6lcmOgUFcYUZIMhVgYhdo=", + "owner": "protolude", + "repo": "protolude", + "rev": "d821ef0ac7552cfa2c3e7a7bdf29539f57e3fae6", + "type": "github" + }, + "original": { + "owner": "protolude", + "repo": "protolude", + "rev": "d821ef0ac7552cfa2c3e7a7bdf29539f57e3fae6", + "type": "github" + } + }, "protolude_2": { "flake": false, "locked": { @@ -9322,17 +10428,16 @@ "protolude_9": { "flake": false, "locked": { - "lastModified": 1637276813, - "narHash": "sha256-/mgR1Vyp1WYBjdkbwQycrf6lcmOgUFcYUZIMhVgYhdo=", + "lastModified": 1647139352, + "narHash": "sha256-JyHAQfTTUswP8MeGEZibx/2/v01Q7cU5mNpnmDazh24=", "owner": "protolude", "repo": "protolude", - "rev": "d821ef0ac7552cfa2c3e7a7bdf29539f57e3fae6", + "rev": "3e249724fd0ead27370c8c297b1ecd38f92cbd5b", "type": "github" }, "original": { "owner": "protolude", "repo": "protolude", - "rev": "d821ef0ac7552cfa2c3e7a7bdf29539f57e3fae6", "type": "github" } }, @@ -9484,6 +10589,22 @@ "type": "github" } }, + "secp256k1-haskell_9": { + "flake": false, + "locked": { + "lastModified": 1650290419, + "narHash": "sha256-XrjiqCC7cNTFib78gdMPGNettAkwAxQlbC/n+/mRFt4=", + "owner": "haskoin", + "repo": "secp256k1-haskell", + "rev": "3df963ab6ae14ec122691a97af09a7331511a387", + "type": "github" + }, + "original": { + "owner": "haskoin", + "repo": "secp256k1-haskell", + "type": "github" + } + }, "sized-functors": { "flake": false, "locked": { @@ -9517,6 +10638,22 @@ "type": "github" } }, + "sphinxcontrib-haddock_10": { + "flake": false, + "locked": { + "lastModified": 1594136664, + "narHash": "sha256-O9YT3iCUBHP3CEF88VDLLCO2HSP3HqkNA2q2939RnVY=", + "owner": "michaelpj", + "repo": "sphinxcontrib-haddock", + "rev": "f3956b3256962b2d27d5a4e96edb7951acf5de34", + "type": "github" + }, + "original": { + "owner": "michaelpj", + "repo": "sphinxcontrib-haddock", + "type": "github" + } + }, "sphinxcontrib-haddock_2": { "flake": false, "locked": { @@ -9677,6 +10814,22 @@ "type": "github" } }, + "stackage_10": { + "flake": false, + "locked": { + "lastModified": 1644887829, + "narHash": "sha256-tjUXJpqB7MMnqM4FF5cdtZipfratUcTKRQVA6F77sEQ=", + "owner": "input-output-hk", + "repo": "stackage.nix", + "rev": "db8bdef6588cf4f38e6069075ba76f0024381f68", + "type": "github" + }, + "original": { + "owner": "input-output-hk", + "repo": "stackage.nix", + "type": "github" + } + }, "stackage_2": { "flake": false, "locked": { @@ -9792,11 +10945,11 @@ "stackage_9": { "flake": false, "locked": { - "lastModified": 1644887829, - "narHash": "sha256-tjUXJpqB7MMnqM4FF5cdtZipfratUcTKRQVA6F77sEQ=", + "lastModified": 1654046327, + "narHash": "sha256-IxX46Dh4OZpF3k7KPMa3tZSScYYGqFxXpCnMc0QRkuQ=", "owner": "input-output-hk", "repo": "stackage.nix", - "rev": "db8bdef6588cf4f38e6069075ba76f0024381f68", + "rev": "cc1d778723fcd431f9b2ed632a50c610c3e38b54", "type": "github" }, "original": { @@ -9973,6 +11126,8 @@ "inputs": { "ema": [ "plutarch-safe-money", + "liqwid-plutarch-extra", + "plutarch-quickcheck", "plutarch", "emanote", "ema" @@ -9998,9 +11153,36 @@ }, "tailwind-haskell_8": { "inputs": { - "flake-compat": "flake-compat_17", - "flake-utils": "flake-utils_26", - "nixpkgs": "nixpkgs_41" + "ema": [ + "plutarch-safe-money", + "plutarch", + "emanote", + "ema" + ], + "flake-compat": "flake-compat_16", + "flake-utils": "flake-utils_24", + "nixpkgs": "nixpkgs_40" + }, + "locked": { + "lastModified": 1653230344, + "narHash": "sha256-MNwayqvZHsIsP1uyqwQFvzcfFGBMejzZOqAapDjrV5I=", + "owner": "srid", + "repo": "tailwind-haskell", + "rev": "0fb8a18b0e770bafc17521836658f31c56e6dfdb", + "type": "github" + }, + "original": { + "owner": "srid", + "ref": "master", + "repo": "tailwind-haskell", + "type": "github" + } + }, + "tailwind-haskell_9": { + "inputs": { + "flake-compat": "flake-compat_19", + "flake-utils": "flake-utils_29", + "nixpkgs": "nixpkgs_46" }, "locked": { "lastModified": 1649519562, @@ -10036,9 +11218,9 @@ }, "unionmount": { "inputs": { - "flake-compat": "flake-compat_18", - "flake-utils": "flake-utils_27", - "nixpkgs": "nixpkgs_42" + "flake-compat": "flake-compat_20", + "flake-utils": "flake-utils_30", + "nixpkgs": "nixpkgs_47" }, "locked": { "lastModified": 1649012450, diff --git a/flake.nix b/flake.nix index 611c21c..5c5c29d 100644 --- a/flake.nix +++ b/flake.nix @@ -21,7 +21,7 @@ inputs.plutarch-numeric.url = "github:Liqwid-Labs/plutarch-numeric?ref=main"; inputs.plutarch-safe-money.url = - "github:Liqwid-Labs/plutarch-safe-money?ref=main"; + "github:Liqwid-Labs/plutarch-safe-money?rev=9f968b80189c7e4b335527cd5b103dc26952f667"; # Testing inputs.plutarch-quickcheck.url =