fix compilation errors

This commit is contained in:
Hongrui Fang 2022-11-03 02:13:21 +08:00
parent d921927a2f
commit 6da4e7286d
No known key found for this signature in database
GPG key ID: F10AB2CCE24113DD
21 changed files with 279 additions and 677 deletions

View file

@ -7,232 +7,236 @@ Property model and tests for 'Governor' related functions
-} -}
module Property.Governor (props) where module Property.Governor (props) where
import Agora.Governor (Governor (gstOutRef), GovernorDatum (..), pisGovernorDatumValid) -- import Agora.Governor (Governor (gstOutRef), GovernorDatum (..), pisGovernorDatumValid)
import Agora.Governor.Scripts (governorPolicy) -- import Agora.Governor.Scripts (governorPolicy)
import Agora.Proposal ( -- import Agora.Proposal (
ProposalId (ProposalId), -- ProposalId (ProposalId),
ProposalThresholds (ProposalThresholds), -- ProposalThresholds (ProposalThresholds),
) -- )
import Agora.Proposal.Time ( -- import Agora.Proposal.Time (
MaxTimeRangeWidth (MaxTimeRangeWidth), -- MaxTimeRangeWidth (MaxTimeRangeWidth),
ProposalTimingConfig (ProposalTimingConfig), -- ProposalTimingConfig (ProposalTimingConfig),
) -- )
import Data.Default.Class (Default (def)) -- import Data.Default.Class (Default (def))
import Data.Tagged (Tagged (Tagged)) -- import Data.Tagged (Tagged (Tagged))
import Data.Universe (Finite (..), Universe (..)) -- import Data.Universe (Finite (..), Universe (..))
import Plutarch.Api.V2 (PScriptContext) -- import Plutarch.Api.V2 (PScriptContext)
import Plutarch.Builtin (pforgetData) -- import Plutarch.Builtin (pforgetData)
import Plutarch.Context ( -- import Plutarch.Context (
MintingBuilder, -- MintingBuilder,
buildMinting', -- buildMinting',
input, -- input,
mint, -- mint,
output, -- output,
script, -- script,
withDatum, -- withDatum,
withMinting, -- withMinting,
withRef, -- withRef,
withValue, -- withValue,
) -- )
import Plutarch.Extra.AssetClass (assetClassValue) -- import Plutarch.Extra.AssetClass (assetClassValue)
import PlutusLedgerApi.V2 ( -- import PlutusLedgerApi.V2 (
ScriptContext (scriptContextTxInfo), -- ScriptContext (scriptContextTxInfo),
TxInInfo (txInInfoOutRef), -- TxInInfo (txInInfoOutRef),
TxInfo (txInfoInputs, txInfoMint, txInfoOutputs), -- TxInfo (txInfoInputs, txInfoMint, txInfoOutputs),
TxOut (txOutValue), -- TxOut (txOutValue),
) -- )
import Property.Generator (genInput, genOutput) -- import Property.Generator (genInput, genOutput)
import Sample.Shared ( -- import Sample.Shared (
governor, -- governor,
governorAssetClass, -- governorAssetClass,
governorSymbol, -- governorSymbol,
governorValidatorHash, -- governorValidatorHash,
gstUTXORef, -- gstUTXORef,
) -- )
import Test.Tasty (TestTree) import Test.Tasty (TestTree)
import Test.Tasty.Plutarch.Property (classifiedPropertyNative)
import Test.Tasty.QuickCheck (
Gen,
Property,
choose,
chooseInteger,
listOf1,
testProperty,
)
data GovernorDatumCases -- import Test.Tasty.Plutarch.Property (classifiedPropertyNative)
= ExecuteLE0 -- import Test.Tasty.QuickCheck (
| CreateLE0 -- Gen,
| ToVotingLE0 -- Property,
| VoteLE0 -- choose,
| CosignLE0 -- chooseInteger,
| Correct -- listOf1,
deriving stock (Eq, Show) -- testProperty,
-- )
instance Universe GovernorDatumCases where -- data GovernorDatumCases
universe = -- = ExecuteLE0
[ ExecuteLE0 -- | CreateLE0
, CreateLE0 -- | ToVotingLE0
, VoteLE0 -- | VoteLE0
, CosignLE0 -- | CosignLE0
, Correct -- | Correct
] -- deriving stock (Eq, Show)
instance Finite GovernorDatumCases where -- instance Universe GovernorDatumCases where
universeF = universe -- universe =
cardinality = Tagged 6 -- [ ExecuteLE0
-- , CreateLE0
-- , VoteLE0
-- , CosignLE0
-- , Correct
-- ]
{- | Property that checks `governorDatumValid`. -- instance Finite GovernorDatumCases where
`governorDatumValid` determines if given governor datum is valid or not. This property -- universeF = universe
ensures `governorDatumValid` is checking the datum correctly and ruling out improper datum. -- cardinality = Tagged 6
-}
governorDatumValidProperty :: Property
governorDatumValidProperty =
classifiedPropertyNative gen (const []) expected classifier pisGovernorDatumValid
where
classifier :: GovernorDatum -> GovernorDatumCases
classifier
( (.proposalThresholds) ->
ProposalThresholds
execute
create
toVoting
vote
cosign
)
| execute < 0 = ExecuteLE0
| create < 0 = CreateLE0
| toVoting < 0 = ToVotingLE0
| vote < 0 = VoteLE0
| cosign < 0 = CosignLE0
| otherwise = Correct
expected :: GovernorDatum -> Maybe Bool -- {- | Property that checks `governorDatumValid`.
expected c = Just $ classifier c == Correct -- `governorDatumValid` determines if given governor datum is valid or not. This property
-- ensures `governorDatumValid` is checking the datum correctly and ruling out improper datum.
-- -}
-- governorDatumValidProperty :: Property
-- governorDatumValidProperty =
-- classifiedPropertyNative gen (const []) expected classifier pisGovernorDatumValid
-- where
-- classifier :: GovernorDatum -> GovernorDatumCases
-- classifier
-- ( (.proposalThresholds) ->
-- ProposalThresholds
-- execute
-- create
-- toVoting
-- vote
-- cosign
-- )
-- | execute < 0 = ExecuteLE0
-- | create < 0 = CreateLE0
-- | toVoting < 0 = ToVotingLE0
-- | vote < 0 = VoteLE0
-- | cosign < 0 = CosignLE0
-- | otherwise = Correct
gen :: GovernorDatumCases -> Gen GovernorDatum -- expected :: GovernorDatum -> Maybe Bool
gen c = do -- expected c = Just $ classifier c == Correct
thres <- genProposalThresholds c
let timing = ProposalTimingConfig 0 0 0 0 -- gen :: GovernorDatumCases -> Gen GovernorDatum
return $ GovernorDatum thres (ProposalId 0) timing (MaxTimeRangeWidth 1) 3 -- gen c = do
where -- thres <- genProposalThresholds c
taggedInteger p = Tagged <$> chooseInteger p
genProposalThresholds :: GovernorDatumCases -> Gen ProposalThresholds
genProposalThresholds c = do
let validGT = taggedInteger (0, 1000000000)
execute <- validGT
create <- validGT
toVoting <- validGT
vote <- validGT
cosign <- validGT
le0 <- taggedInteger (-1000, -1)
case c of -- let timing = ProposalTimingConfig 0 0 0 0
ExecuteLE0 -> -- return $ GovernorDatum thres (ProposalId 0) timing (MaxTimeRangeWidth 1) 3
-- execute < 0 -- where
return $ ProposalThresholds le0 create toVoting vote cosign -- taggedInteger p = Tagged <$> chooseInteger p
CreateLE0 -> -- genProposalThresholds :: GovernorDatumCases -> Gen ProposalThresholds
-- c < 0 -- genProposalThresholds c = do
return $ ProposalThresholds execute le0 toVoting vote cosign -- let validGT = taggedInteger (0, 1000000000)
ToVotingLE0 -> -- execute <- validGT
return $ ProposalThresholds execute create le0 vote cosign -- create <- validGT
VoteLE0 -> -- toVoting <- validGT
-- vote < 0 -- vote <- validGT
return $ ProposalThresholds execute create toVoting le0 cosign -- cosign <- validGT
CosignLE0 -> -- le0 <- taggedInteger (-1000, -1)
return $ ProposalThresholds execute create toVoting vote le0
Correct ->
return $ ProposalThresholds execute create toVoting vote cosign
data GovernorPolicyCases -- case c of
= ReferenceUTXONotSpent -- ExecuteLE0 ->
| IncorrectAmountOfTokenMinted -- -- execute < 0
| GovernorOutputNotFound -- return $ ProposalThresholds le0 create toVoting vote cosign
| GovernorPolicyCorrect -- CreateLE0 ->
deriving stock (Eq, Show) -- -- c < 0
-- return $ ProposalThresholds execute le0 toVoting vote cosign
-- ToVotingLE0 ->
-- return $ ProposalThresholds execute create le0 vote cosign
-- VoteLE0 ->
-- -- vote < 0
-- return $ ProposalThresholds execute create toVoting le0 cosign
-- CosignLE0 ->
-- return $ ProposalThresholds execute create toVoting vote le0
-- Correct ->
-- return $ ProposalThresholds execute create toVoting vote cosign
instance Universe GovernorPolicyCases where -- data GovernorPolicyCases
universe = -- = ReferenceUTXONotSpent
[ ReferenceUTXONotSpent -- | IncorrectAmountOfTokenMinted
, IncorrectAmountOfTokenMinted -- | GovernorOutputNotFound
, GovernorOutputNotFound -- | GovernorPolicyCorrect
, GovernorPolicyCorrect -- deriving stock (Eq, Show)
]
instance Finite GovernorPolicyCases where -- instance Universe GovernorPolicyCases where
universeF = universe -- universe =
cardinality = Tagged 4 -- [ ReferenceUTXONotSpent
-- , IncorrectAmountOfTokenMinted
-- , GovernorOutputNotFound
-- , GovernorPolicyCorrect
-- ]
governorMintingProperty :: Property -- instance Finite GovernorPolicyCases where
governorMintingProperty = -- universeF = universe
classifiedPropertyNative gen (const []) expected classifier actual -- cardinality = Tagged 4
where
{- Note:
I don't think it's easily possible to randomize orefs. We can't really pass pass `Governor` type to `actual` function.
-}
gst = assetClassValue governorAssetClass 1
mintAmount x = mint . mconcat $ replicate x gst
outputToGov =
output $
mconcat
[ script governorValidatorHash
, withValue gst
, withDatum govDatum
]
referencedInput = input $ withRef gstUTXORef
govDatum :: GovernorDatum -- governorMintingProperty :: Property
govDatum = -- governorMintingProperty =
GovernorDatum -- classifiedPropertyNative gen (const []) expected classifier actual
{ proposalThresholds = def -- where
, nextProposalId = ProposalId 0 -- {- Note:
, proposalTimings = def -- I don't think it's easily possible to randomize orefs. We can't really pass pass `Governor` type to `actual` function.
, createProposalTimeRangeMaxWidth = def -- -}
, maximumProposalsPerStake = 3 -- gst = assetClassValue governorAssetClass 1
} -- mintAmount x = mint . mconcat $ replicate x gst
-- outputToGov =
-- output $
-- mconcat
-- [ script governorValidatorHash
-- , withValue gst
-- , withDatum govDatum
-- ]
-- referencedInput = input $ withRef gstUTXORef
gen :: GovernorPolicyCases -> Gen ScriptContext -- govDatum :: GovernorDatum
gen c = do -- govDatum =
inputs <- fmap mconcat . listOf1 $ genInput @MintingBuilder -- GovernorDatum
outputs <- fmap mconcat . listOf1 $ genOutput @MintingBuilder -- { proposalThresholds = def
toks <- choose (2, 100) -- , nextProposalId = ProposalId 0
-- , proposalTimings = def
-- , createProposalTimeRangeMaxWidth = def
-- , maximumProposalsPerStake = 3
-- }
let comp = -- gen :: GovernorPolicyCases -> Gen ScriptContext
case c of -- gen c = do
ReferenceUTXONotSpent -> outputToGov <> mintAmount 1 -- inputs <- fmap mconcat . listOf1 $ genInput @MintingBuilder
IncorrectAmountOfTokenMinted -> referencedInput <> outputToGov <> mintAmount toks -- outputs <- fmap mconcat . listOf1 $ genOutput @MintingBuilder
GovernorOutputNotFound -> referencedInput <> mintAmount 1 -- toks <- choose (2, 100)
GovernorPolicyCorrect -> referencedInput <> outputToGov <> mintAmount 1
return . buildMinting' $ inputs <> outputs <> comp <> withMinting governorSymbol -- let comp =
-- case c of
-- ReferenceUTXONotSpent -> outputToGov <> mintAmount 1
-- IncorrectAmountOfTokenMinted -> referencedInput <> outputToGov <> mintAmount toks
-- GovernorOutputNotFound -> referencedInput <> mintAmount 1
-- GovernorPolicyCorrect -> referencedInput <> outputToGov <> mintAmount 1
expected :: ScriptContext -> Maybe () -- return . buildMinting' $ inputs <> outputs <> comp <> withMinting governorSymbol
expected sc =
case classifier sc of
GovernorPolicyCorrect -> Just ()
_ -> Nothing
opaqueToUnit :: Term s (POpaque :--> PUnit) -- expected :: ScriptContext -> Maybe ()
opaqueToUnit = plam $ \_ -> pconstant () -- expected sc =
-- case classifier sc of
-- GovernorPolicyCorrect -> Just ()
-- _ -> Nothing
actual :: Term s (PScriptContext :--> PUnit) -- opaqueToUnit :: Term s (POpaque :--> PUnit)
actual = plam $ \sc -> opaqueToUnit #$ governorPolicy # pconstant governor.gstOutRef # pforgetData (pconstantData ()) # sc -- opaqueToUnit = plam $ \_ -> pconstant ()
classifier :: ScriptContext -> GovernorPolicyCases -- actual :: Term s (PScriptContext :--> PUnit)
classifier sc -- actual = plam $ \sc -> opaqueToUnit #$ governorPolicy # pconstant governor.gstOutRef # pforgetData (pconstantData ()) # sc
| minted /= gst = IncorrectAmountOfTokenMinted
| refInputNotExists = ReferenceUTXONotSpent -- classifier :: ScriptContext -> GovernorPolicyCases
| govOutputNotExists = GovernorOutputNotFound -- classifier sc
| otherwise = GovernorPolicyCorrect -- | minted /= gst = IncorrectAmountOfTokenMinted
where -- | refInputNotExists = ReferenceUTXONotSpent
txinfo = scriptContextTxInfo sc -- | govOutputNotExists = GovernorOutputNotFound
minted = txInfoMint txinfo -- | otherwise = GovernorPolicyCorrect
refInputNotExists = gstUTXORef `notElem` (txInInfoOutRef <$> txInfoInputs txinfo) -- where
govOutputNotExists = gst `notElem` (txOutValue <$> txInfoOutputs txinfo) -- txinfo = scriptContextTxInfo sc
-- minted = txInfoMint txinfo
-- refInputNotExists = gstUTXORef `notElem` (txInInfoOutRef <$> txInfoInputs txinfo)
-- govOutputNotExists = gst `notElem` (txOutValue <$> txInfoOutputs txinfo)
-- props :: [TestTree]
-- props =
-- [ testProperty "governorDatumValid" governorDatumValidProperty
-- , testProperty "governorPolicy" governorMintingProperty
-- ]
props :: [TestTree] props :: [TestTree]
props = props = []
[ testProperty "governorDatumValid" governorDatumValidProperty
, testProperty "governorPolicy" governorMintingProperty
]

View file

@ -4,9 +4,9 @@ module Sample.AuthorityToken.UnauthorizedMintingExploit (
mkTestCase, mkTestCase,
) where ) where
import Agora.Utils (validatorHashToTokenName)
import Control.Exception (assert) import Control.Exception (assert)
import Plutarch.Context (input, mint, normalizeValue, output, script, withValue) import Plutarch.Context (input, mint, normalizeValue, output, script, withValue)
import Plutarch.Extra.ScriptContext (validatorHashToTokenName)
import PlutusLedgerApi.V1.Value qualified as Value import PlutusLedgerApi.V1.Value qualified as Value
import Sample.Shared (authorityTokenPolicy, authorityTokenSymbol, minAda) import Sample.Shared (authorityTokenPolicy, authorityTokenSymbol, minAda)
import Test.Specification (SpecificationTree, testPolicy) import Test.Specification (SpecificationTree, testPolicy)

View file

@ -17,12 +17,12 @@ import Agora.Effect.GovernorMutation (
import Agora.Governor (GovernorDatum (..), GovernorRedeemer (MutateGovernor)) import Agora.Governor (GovernorDatum (..), GovernorRedeemer (MutateGovernor))
import Agora.Proposal (ProposalId (..), ProposalThresholds (..)) import Agora.Proposal (ProposalId (..), ProposalThresholds (..))
import Agora.SafeMoney (AuthorityTokenTag) import Agora.SafeMoney (AuthorityTokenTag)
import Agora.Utils (validatorHashToTokenName)
import Data.Default.Class (Default (def)) import Data.Default.Class (Default (def))
import Data.Map ((!)) import Data.Map ((!))
import Data.Tagged (Tagged (..)) import Data.Tagged (Tagged (..))
import Plutarch.Api.V2 (validatorHash) import Plutarch.Api.V2 (validatorHash)
import Plutarch.Extra.AssetClass (AssetClass (AssetClass), assetClassValue) import Plutarch.Extra.AssetClass (AssetClass (AssetClass), assetClassValue)
import Plutarch.Extra.ScriptContext (validatorHashToTokenName)
import PlutusLedgerApi.V1 qualified as Interval (always) import PlutusLedgerApi.V1 qualified as Interval (always)
import PlutusLedgerApi.V1.Address (scriptHashAddress) import PlutusLedgerApi.V1.Address (scriptHashAddress)
import PlutusLedgerApi.V1.Value qualified as Value ( import PlutusLedgerApi.V1.Value qualified as Value (

View file

@ -18,7 +18,6 @@ module Sample.Governor.Mutate (
import Agora.Governor (GovernorDatum (..), GovernorRedeemer (MutateGovernor)) import Agora.Governor (GovernorDatum (..), GovernorRedeemer (MutateGovernor))
import Agora.Proposal (ProposalId (ProposalId), ProposalThresholds (..)) import Agora.Proposal (ProposalId (ProposalId), ProposalThresholds (..))
import Agora.Utils (scriptHashToTokenName)
import Data.Default (def) import Data.Default (def)
import Data.Map ((!)) import Data.Map ((!))
import Plutarch.Api.V2 (PMintingPolicy, mintingPolicySymbol, mkMintingPolicy, validatorHash) import Plutarch.Api.V2 (PMintingPolicy, mintingPolicySymbol, mkMintingPolicy, validatorHash)
@ -33,6 +32,7 @@ import Plutarch.Context (
withValue, withValue,
) )
import Plutarch.Extra.AssetClass (assetClassValue) import Plutarch.Extra.AssetClass (assetClassValue)
import Plutarch.Extra.ScriptContext (scriptHashToTokenName)
import PlutusLedgerApi.V1.Value qualified as Value import PlutusLedgerApi.V1.Value qualified as Value
import PlutusLedgerApi.V2 ( import PlutusLedgerApi.V2 (
CurrencySymbol (CurrencySymbol), CurrencySymbol (CurrencySymbol),

View file

@ -68,7 +68,6 @@ import Agora.SafeMoney (AuthorityTokenTag, GTTag)
import Agora.Stake ( import Agora.Stake (
StakeDatum (..), StakeDatum (..),
) )
import Agora.Utils (scriptHashToTokenName)
import Control.Applicative (liftA2) import Control.Applicative (liftA2)
import Control.Monad.State (execState, modify, when) import Control.Monad.State (execState, modify, when)
import Data.Default (def) import Data.Default (def)
@ -90,6 +89,7 @@ import Plutarch.Context (
withValue, withValue,
) )
import Plutarch.Extra.AssetClass (AssetClass (AssetClass), assetClassValue) import Plutarch.Extra.AssetClass (AssetClass (AssetClass), assetClassValue)
import Plutarch.Extra.ScriptContext (scriptHashToTokenName)
import Plutarch.Lift (PLifted, PUnsafeLiftDecl) import Plutarch.Lift (PLifted, PUnsafeLiftDecl)
import PlutusLedgerApi.V2 ( import PlutusLedgerApi.V2 (
Credential (PubKeyCredential), Credential (PubKeyCredential),

View file

@ -46,7 +46,6 @@ import Agora.Stake (
StakeDatum (..), StakeDatum (..),
StakeRedeemer (PermitVote), StakeRedeemer (PermitVote),
) )
import Agora.Utils (validatorHashToTokenName)
import Data.Coerce (coerce) import Data.Coerce (coerce)
import Data.Default (Default (def)) import Data.Default (Default (def))
import Data.Map.Strict qualified as StrictMap import Data.Map.Strict qualified as StrictMap
@ -66,6 +65,7 @@ import Plutarch.Context (
withValue, withValue,
) )
import Plutarch.Extra.AssetClass (assetClassValue) import Plutarch.Extra.AssetClass (assetClassValue)
import Plutarch.Extra.ScriptContext (validatorHashToTokenName)
import PlutusLedgerApi.V1.Value qualified as Value import PlutusLedgerApi.V1.Value qualified as Value
import PlutusLedgerApi.V2 ( import PlutusLedgerApi.V2 (
Credential (PubKeyCredential), Credential (PubKeyCredential),

View file

@ -49,7 +49,6 @@ import Agora.Stake (
StakeDatum (..), StakeDatum (..),
StakeRedeemer (RetractVotes), StakeRedeemer (RetractVotes),
) )
import Agora.Utils (validatorHashToTokenName)
import Data.Default.Class (Default (def)) import Data.Default.Class (Default (def))
import Data.Map.Strict qualified as StrictMap import Data.Map.Strict qualified as StrictMap
import Data.Tagged (Tagged, untag) import Data.Tagged (Tagged, untag)
@ -67,6 +66,7 @@ import Plutarch.Context (
withValue, withValue,
) )
import Plutarch.Extra.AssetClass (assetClassValue) import Plutarch.Extra.AssetClass (assetClassValue)
import Plutarch.Extra.ScriptContext (validatorHashToTokenName)
import PlutusLedgerApi.V1.Value qualified as Value import PlutusLedgerApi.V1.Value qualified as Value
import PlutusLedgerApi.V2 ( import PlutusLedgerApi.V2 (
Credential (PubKeyCredential), Credential (PubKeyCredential),

View file

@ -72,9 +72,6 @@ import Agora.Proposal.Time (
ProposalTimingConfig (..), ProposalTimingConfig (..),
) )
import Agora.SafeMoney (GovernorSTTag, ProposalSTTag, StakeSTTag) import Agora.SafeMoney (GovernorSTTag, ProposalSTTag, StakeSTTag)
import Agora.Utils (
validatorHashToTokenName,
)
import Data.Default.Class (Default (..)) import Data.Default.Class (Default (..))
import Data.Map (Map, (!)) import Data.Map (Map, (!))
import Data.Tagged (Tagged (..)) import Data.Tagged (Tagged (..))
@ -86,6 +83,7 @@ import Plutarch.Api.V2 (
validatorHash, validatorHash,
) )
import Plutarch.Extra.AssetClass (AssetClass (AssetClass)) import Plutarch.Extra.AssetClass (AssetClass (AssetClass))
import Plutarch.Extra.ScriptContext (validatorHashToTokenName)
import PlutusLedgerApi.V1.Address (scriptHashAddress) import PlutusLedgerApi.V1.Address (scriptHashAddress)
import PlutusLedgerApi.V1.Value (TokenName, Value) import PlutusLedgerApi.V1.Value (TokenName, Value)
import PlutusLedgerApi.V1.Value qualified as Value ( import PlutusLedgerApi.V1.Value qualified as Value (

View file

@ -21,7 +21,6 @@ import Agora.Governor (Governor (gtClassRef))
import Agora.Proposal (ProposalId (ProposalId)) import Agora.Proposal (ProposalId (ProposalId))
import Agora.SafeMoney (GTTag) import Agora.SafeMoney (GTTag)
import Agora.Stake (ProposalLock (Created), StakeDatum (..)) import Agora.Stake (ProposalLock (Created), StakeDatum (..))
import Agora.Utils (validatorHashToTokenName)
import Data.Semigroup (stimesMonoid) import Data.Semigroup (stimesMonoid)
import Data.Tagged (Tagged) import Data.Tagged (Tagged)
import Plutarch.Context ( import Plutarch.Context (
@ -36,6 +35,7 @@ import Plutarch.Context (
withValue, withValue,
) )
import Plutarch.Extra.AssetClass (assetClassValue) import Plutarch.Extra.AssetClass (assetClassValue)
import Plutarch.Extra.ScriptContext (validatorHashToTokenName)
import Plutarch.Lift (PUnsafeLiftDecl (PLifted)) import Plutarch.Lift (PUnsafeLiftDecl (PLifted))
import PlutusLedgerApi.V1.Value qualified as Value import PlutusLedgerApi.V1.Value qualified as Value
import PlutusLedgerApi.V2 ( import PlutusLedgerApi.V2 (

View file

@ -4,7 +4,6 @@ module Sample.Stake.UnauthorizedMintingExploit (
mkTestCase, mkTestCase,
) where ) where
import Agora.Utils (validatorHashToTokenName)
import Plutarch.Context ( import Plutarch.Context (
input, input,
mint, mint,
@ -14,6 +13,7 @@ import Plutarch.Context (
withValue, withValue,
) )
import Plutarch.Extra.AssetClass (assetClassValue) import Plutarch.Extra.AssetClass (assetClassValue)
import Plutarch.Extra.ScriptContext (validatorHashToTokenName)
import PlutusLedgerApi.V1.Value qualified as Value import PlutusLedgerApi.V1.Value qualified as Value
import Sample.Shared ( import Sample.Shared (
minAda, minAda,

View file

@ -11,10 +11,6 @@ module Agora.AuthorityToken (
singleAuthorityTokenBurned, singleAuthorityTokenBurned,
) where ) where
import Agora.Utils (
passert,
psymbolValueOf',
)
import Plutarch.Api.V1 ( import Plutarch.Api.V1 (
PCredential (..), PCredential (..),
PCurrencySymbol (..), PCurrencySymbol (..),
@ -33,6 +29,7 @@ import Plutarch.Api.V2 (
PTxOut (PTxOut), PTxOut (PTxOut),
) )
import Plutarch.Extra.AssetClass (PAssetClassData, ptoScottEncoding) import Plutarch.Extra.AssetClass (PAssetClassData, ptoScottEncoding)
import Plutarch.Extra.Bool (passert)
import "liqwid-plutarch-extra" Plutarch.Extra.List (plookupAssoc) import "liqwid-plutarch-extra" Plutarch.Extra.List (plookupAssoc)
import Plutarch.Extra.Maybe (pfromJust) import Plutarch.Extra.Maybe (pfromJust)
import Plutarch.Extra.ScriptContext (pisTokenSpent) import Plutarch.Extra.ScriptContext (pisTokenSpent)
@ -44,7 +41,7 @@ import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (
pmatchC, pmatchC,
) )
import Plutarch.Extra.Traversable (pfoldMap) import Plutarch.Extra.Traversable (pfoldMap)
import Plutarch.Extra.Value (psymbolValueOf) import Plutarch.Extra.Value (psymbolValueOf, psymbolValueOf')
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View file

@ -26,7 +26,6 @@ import Agora.Governor (
PGovernorRedeemer, PGovernorRedeemer,
) )
import Agora.Plutarch.Orphans () import Agora.Plutarch.Orphans ()
import Agora.Utils (pfromSingleton, ptryFromRedeemer)
import Plutarch.Api.V1 (PCurrencySymbol, PValidatorHash) import Plutarch.Api.V1 (PCurrencySymbol, PValidatorHash)
import Plutarch.Api.V2 ( import Plutarch.Api.V2 (
PScriptPurpose (PSpending), PScriptPurpose (PSpending),
@ -38,9 +37,15 @@ import Plutarch.DataRepr (
PDataFields, PDataFields,
) )
import Plutarch.Extra.Field (pletAll, pletAllC) import Plutarch.Extra.Field (pletAll, pletAllC)
import "liqwid-plutarch-extra" Plutarch.Extra.List (ptryFromSingleton)
import Plutarch.Extra.Maybe (passertPJust, pdnothing) import Plutarch.Extra.Maybe (passertPJust, pdnothing)
import Plutarch.Extra.Record (mkRecordConstr, (.=)) import Plutarch.Extra.Record (mkRecordConstr, (.=))
import Plutarch.Extra.ScriptContext (paddressFromValidatorHash, pfromOutputDatum, pisScriptAddress) import Plutarch.Extra.ScriptContext (
paddressFromValidatorHash,
pisScriptAddress,
ptryFromOutputDatum,
ptryFromRedeemer,
)
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pguardC, pletC, pletFieldsC) import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pguardC, pletC, pletFieldsC)
import Plutarch.Extra.Value (psymbolValueOf) import Plutarch.Extra.Value (psymbolValueOf)
import Plutarch.Lift (PConstantDecl, PLifted, PUnsafeLiftDecl) import Plutarch.Lift (PConstantDecl, PLifted, PUnsafeLiftDecl)
@ -216,11 +221,11 @@ mutateGovernorValidator =
let governorOutput = let governorOutput =
ptrace "Only governor output is allowed" $ ptrace "Only governor output is allowed" $
pfromSingleton # pfromData txInfoF.outputs ptryFromSingleton # pfromData txInfoF.outputs
governorOutputDatum = governorOutputDatum =
ptrace "Resolve governor outoput datum" $ ptrace "Resolve governor outoput datum" $
pfromOutputDatum @PGovernorDatum ptryFromOutputDatum @PGovernorDatum
# (pfield @"datum" # governorOutput) # (pfield @"datum" # governorOutput)
# txInfoF.datums # txInfoF.datums

View file

@ -15,7 +15,6 @@ module Agora.Effect.TreasuryWithdrawal (
import Agora.Effect (makeEffect) import Agora.Effect (makeEffect)
import Agora.Plutarch.Orphans () import Agora.Plutarch.Orphans ()
import Agora.Utils (pdelete)
import Plutarch.Api.V1 ( import Plutarch.Api.V1 (
PCredential, PCredential,
PCurrencySymbol, PCurrencySymbol,
@ -35,6 +34,7 @@ import Plutarch.DataRepr (
PDataFields, PDataFields,
) )
import Plutarch.Extra.Field (pletAllC) import Plutarch.Extra.Field (pletAllC)
import "liqwid-plutarch-extra" Plutarch.Extra.List (pdeleteFirst)
import Plutarch.Extra.ScriptContext (pisPubKey) import Plutarch.Extra.ScriptContext (pisPubKey)
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pguardC, pletC, pletFieldsC) import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pguardC, pletC, pletFieldsC)
import Plutarch.Lift (PConstantDecl, PUnsafeLiftDecl (PLifted)) import Plutarch.Lift (PConstantDecl, PUnsafeLiftDecl (PLifted))
@ -178,7 +178,7 @@ treasuryWithdrawalValidator = plam $
(ptraceError "Invalid receiver") (ptraceError "Invalid receiver")
pure $ pure $
pmatch (pdelete # credValue # receivers) $ \case pmatch (pdeleteFirst # credValue # receivers) $ \case
PJust updatedReceivers -> PJust updatedReceivers ->
ptrace "Receiver output" updatedReceivers ptrace "Receiver output" updatedReceivers
PNothing -> PNothing ->

View file

@ -40,10 +40,6 @@ import Agora.Stake (
pnumCreatedProposals, pnumCreatedProposals,
presolveStakeInputDatum, presolveStakeInputDatum,
) )
import Agora.Utils (
plistEqualsBy,
pscriptHashToTokenName,
)
import Plutarch.Api.V1 (PCurrencySymbol) import Plutarch.Api.V1 (PCurrencySymbol)
import Plutarch.Api.V1.AssocMap (plookup) import Plutarch.Api.V1.AssocMap (plookup)
import Plutarch.Api.V1.AssocMap qualified as AssocMap import Plutarch.Api.V1.AssocMap qualified as AssocMap
@ -57,17 +53,18 @@ import Plutarch.Api.V2 (
) )
import Plutarch.Extra.AssetClass (PAssetClassData, passetClass, ptoScottEncoding) import Plutarch.Extra.AssetClass (PAssetClassData, passetClass, ptoScottEncoding)
import Plutarch.Extra.Field (pletAll, pletAllC) import Plutarch.Extra.Field (pletAll, pletAllC)
import "liqwid-plutarch-extra" Plutarch.Extra.List (pfindJust, pmapMaybe) import "liqwid-plutarch-extra" Plutarch.Extra.List (pfindJust, plistEqualsBy, pmapMaybe)
import "liqwid-plutarch-extra" Plutarch.Extra.Map (pkeys, ptryLookup) import "liqwid-plutarch-extra" Plutarch.Extra.Map (pkeys, ptryLookup)
import Plutarch.Extra.Maybe (passertPJust, pjust, pmaybe, pmaybeData, pnothing) import Plutarch.Extra.Maybe (passertPJust, pjust, pmaybe, pmaybeData, pnothing)
import Plutarch.Extra.Ord (psort) import Plutarch.Extra.Ord (psort)
import Plutarch.Extra.Record (mkRecordConstr, (.&), (.=)) import Plutarch.Extra.Record (mkRecordConstr, (.&), (.=))
import Plutarch.Extra.ScriptContext ( import Plutarch.Extra.ScriptContext (
pfindTxInByTxOutRef, pfindTxInByTxOutRef,
pfromDatumHash,
pfromOutputDatum,
pisUTXOSpent, pisUTXOSpent,
pscriptHashFromAddress, pscriptHashFromAddress,
pscriptHashToTokenName,
ptryFromDatumHash,
ptryFromOutputDatum,
pvalueSpent, pvalueSpent,
) )
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont ( import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (
@ -153,7 +150,7 @@ governorPolicy =
governorDatum = governorDatum =
ptrace "Resolve governor datum" $ ptrace "Resolve governor datum" $
pfromOutputDatum @PGovernorDatum ptryFromOutputDatum @PGovernorDatum
# txOutF.datum # txOutF.datum
# txInfoF.datums # txInfoF.datums
in pif isGovernorUTxO (pjust # governorDatum) pnothing in pif isGovernorUTxO (pjust # governorDatum) pnothing
@ -323,7 +320,7 @@ governorValidator =
datum = datum =
ptrace "Resolve governor datum" $ ptrace "Resolve governor datum" $
pfromOutputDatum @PGovernorDatum ptryFromOutputDatum @PGovernorDatum
# outputF.datum # outputF.datum
# txInfoF.datums # txInfoF.datums
in pif in pif
@ -350,7 +347,7 @@ governorValidator =
proposalDatum = proposalDatum =
ptrace "Resolve proposal output datum" $ ptrace "Resolve proposal output datum" $
pfromData $ pfromData $
pfromOutputDatum ptryFromOutputDatum
# txOutF.datum # txOutF.datum
# txInfoF.datums # txInfoF.datums
in pif isProposalUTxO (pjust # proposalDatum) pnothing in pif isProposalUTxO (pjust # proposalDatum) pnothing
@ -546,7 +543,7 @@ governorValidator =
#== 1 #== 1
let hasCorrectDatum = let hasCorrectDatum =
effect.datumHash #== pfromDatumHash # outputF.datum effect.datumHash #== ptryFromDatumHash # outputF.datum
pguardC "Authority output valid" $ pguardC "Authority output valid" $
foldr1 foldr1
@ -568,7 +565,7 @@ governorValidator =
-- The sorted hashes of all the GAT receivers. -- The sorted hashes of all the GAT receivers.
actualReceivers = actualReceivers =
psort psort
#$ pmapMaybe #$ pmapMaybe @PList
# getReceiverScriptHash # getReceiverScriptHash
# pfromData txInfoF.outputs # pfromData txInfoF.outputs

View file

@ -3,12 +3,13 @@
module Agora.Linker (linker, AgoraScriptInfo (..)) where module Agora.Linker (linker, AgoraScriptInfo (..)) where
import Agora.Governor (Governor (gstOutRef, gtClassRef, maximumCosigners)) import Agora.Governor (Governor (gstOutRef, gtClassRef, maximumCosigners))
import Agora.Utils (validatorHashToAddress, validatorHashToTokenName) import Agora.Utils (validatorHashToAddress)
import Data.Aeson qualified as Aeson import Data.Aeson qualified as Aeson
import Data.Map (fromList) import Data.Map (fromList)
import Data.Tagged (untag) import Data.Tagged (untag)
import Plutarch.Api.V2 (mintingPolicySymbol, validatorHash) import Plutarch.Api.V2 (mintingPolicySymbol, validatorHash)
import Plutarch.Extra.AssetClass (AssetClass (AssetClass)) import Plutarch.Extra.AssetClass (AssetClass (AssetClass))
import Plutarch.Extra.ScriptContext (validatorHashToTokenName)
import PlutusLedgerApi.V1 (Address, CurrencySymbol, TxOutRef, ValidatorHash) import PlutusLedgerApi.V1 (Address, CurrencySymbol, TxOutRef, ValidatorHash)
import Ply ( import Ply (
ScriptRole (MintingPolicyRole, ValidatorRole), ScriptRole (MintingPolicyRole, ValidatorRole),

View file

@ -35,13 +35,6 @@ import Agora.Stake (
pisVoter, pisVoter,
presolveStakeInputDatum, presolveStakeInputDatum,
) )
import Agora.Utils (
pfromSingleton,
pinsertUniqueBy,
plistEqualsBy,
pmapMaybe,
ptryFromRedeemer,
)
import Plutarch.Api.V1 (PCredential, PCurrencySymbol) import Plutarch.Api.V1 (PCredential, PCurrencySymbol)
import Plutarch.Api.V1.AssocMap (plookup) import Plutarch.Api.V1.AssocMap (plookup)
import Plutarch.Api.V2 ( import Plutarch.Api.V2 (
@ -56,7 +49,12 @@ import Plutarch.Extra.AssetClass (
) )
import Plutarch.Extra.Category (PCategory (pidentity)) import Plutarch.Extra.Category (PCategory (pidentity))
import Plutarch.Extra.Field (pletAll, pletAllC) import Plutarch.Extra.Field (pletAll, pletAllC)
import "liqwid-plutarch-extra" Plutarch.Extra.List (pfindJust) import "liqwid-plutarch-extra" Plutarch.Extra.List (
pfindJust,
plistEqualsBy,
pmapMaybe,
ptryFromSingleton,
)
import "plutarch-extra" Plutarch.Extra.Map (pupdate) import "plutarch-extra" Plutarch.Extra.Map (pupdate)
import Plutarch.Extra.Maybe ( import Plutarch.Extra.Maybe (
passertPJust, passertPJust,
@ -66,11 +64,12 @@ import Plutarch.Extra.Maybe (
pmaybe, pmaybe,
pnothing, pnothing,
) )
import Plutarch.Extra.Ord (pfromOrdBy, psort) import Plutarch.Extra.Ord (pfromOrdBy, pinsertUniqueBy, psort)
import Plutarch.Extra.Record (mkRecordConstr, (.&), (.=)) import Plutarch.Extra.Record (mkRecordConstr, (.&), (.=))
import Plutarch.Extra.ScriptContext ( import Plutarch.Extra.ScriptContext (
pfindTxInByTxOutRef, pfindTxInByTxOutRef,
pfromOutputDatum, ptryFromOutputDatum,
ptryFromRedeemer,
) )
import Plutarch.Extra.Sum (PSum (PSum)) import Plutarch.Extra.Sum (PSum (PSum))
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont ( import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (
@ -309,7 +308,7 @@ proposalValidator =
-- Using inline datum to avoid O(n^2) lookup. -- Using inline datum to avoid O(n^2) lookup.
pfromData $ pfromData $
ptrace "Resolve proposal datum" $ ptrace "Resolve proposal datum" $
pfromOutputDatum @(PAsData PProposalDatum) ptryFromOutputDatum @(PAsData PProposalDatum)
# outputF.datum # outputF.datum
# txInfoF.datums # txInfoF.datums
in pif in pif
@ -348,7 +347,7 @@ proposalValidator =
pletC $ pletC $
plam $ plam $
let stakeInputs = let stakeInputs =
pmapMaybe pmapMaybe @PList
# resolveStakeInputDatum # resolveStakeInputDatum
# pfromData txInfoF.inputs # pfromData txInfoF.inputs
@ -439,7 +438,7 @@ proposalValidator =
stakeF <- stakeF <-
pletFieldsC @'["owner", "stakedAmount"] $ pletFieldsC @'["owner", "stakedAmount"] $
ptrace "Exactly one stake input" $ ptrace "Exactly one stake input" $
pfromSingleton # sctxF.inputStakes ptryFromSingleton # sctxF.inputStakes
let newCosigner = stakeF.owner let newCosigner = stakeF.owner

View file

@ -30,7 +30,6 @@ module Agora.Proposal.Time (
pisWithin, pisWithin,
) where ) where
import Agora.Utils (pcurrentTimeDuration)
import Control.Composition ((.*)) import Control.Composition ((.*))
import Data.Functor ((<&>)) import Data.Functor ((<&>))
import Plutarch.Api.V1 ( import Plutarch.Api.V1 (
@ -52,6 +51,7 @@ import Plutarch.Extra.Maybe (pjust, pmaybe, pnothing)
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pletC, pmatchC) import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pletC, pmatchC)
import Plutarch.Extra.Time ( import Plutarch.Extra.Time (
PCurrentTime (PCurrentTime), PCurrentTime (PCurrentTime),
pcurrentTimeDuration,
pisWithinCurrentTime, pisWithinCurrentTime,
) )
import Plutarch.Lift ( import Plutarch.Lift (

View file

@ -50,7 +50,6 @@ import Agora.Proposal (
ResultTag, ResultTag,
) )
import Agora.SafeMoney (GTTag) import Agora.SafeMoney (GTTag)
import Agora.Utils (pmapMaybe, ppureIf)
import Data.Tagged (Tagged) import Data.Tagged (Tagged)
import Generics.SOP qualified as SOP import Generics.SOP qualified as SOP
import Plutarch.Api.V1 (PCredential) import Plutarch.Api.V1 (PCredential)
@ -67,15 +66,16 @@ import Plutarch.DataRepr (
DerivePConstantViaData (DerivePConstantViaData), DerivePConstantViaData (DerivePConstantViaData),
PDataFields, PDataFields,
) )
import Plutarch.Extra.Applicative (ppureIf)
import Plutarch.Extra.AssetClass (PAssetClass) import Plutarch.Extra.AssetClass (PAssetClass)
import Plutarch.Extra.Field (pletAll) import Plutarch.Extra.Field (pletAll)
import Plutarch.Extra.IsData ( import Plutarch.Extra.IsData (
DerivePConstantViaDataList (DerivePConstantViaDataList), DerivePConstantViaDataList (DerivePConstantViaDataList),
ProductIsData (ProductIsData), ProductIsData (ProductIsData),
) )
import "liqwid-plutarch-extra" Plutarch.Extra.List (pfindJust) import "liqwid-plutarch-extra" Plutarch.Extra.List (pfindJust, pmapMaybe)
import Plutarch.Extra.Maybe (passertPJust, pjust, pnothing) import Plutarch.Extra.Maybe (passertPJust, pjust, pnothing)
import Plutarch.Extra.ScriptContext (pfromOutputDatum) import Plutarch.Extra.ScriptContext (ptryFromOutputDatum)
import Plutarch.Extra.Sum (PSum (PSum)) import Plutarch.Extra.Sum (PSum (PSum))
import Plutarch.Extra.Tagged (PTagged) import Plutarch.Extra.Tagged (PTagged)
import Plutarch.Extra.Traversable (pfoldMap) import Plutarch.Extra.Traversable (pfoldMap)
@ -734,7 +734,7 @@ presolveStakeInputDatum = phoistAcyclic $
datum = datum =
ptrace "Resolve stake datum" $ ptrace "Resolve stake datum" $
pfromData $ pfromData $
pfromOutputDatum @(PAsData PStakeDatum) ptryFromOutputDatum @(PAsData PStakeDatum)
# txOutF.datum # txOutF.datum
# datums # datums
in pif in pif

View file

@ -48,10 +48,10 @@ import Agora.Stake (
), ),
pstakeLocked, pstakeLocked,
) )
import Agora.Utils (pfromSingleton, pisSingleton, pmustDeleteBy)
import Plutarch.Api.V1.Address (PCredential) import Plutarch.Api.V1.Address (PCredential)
import Plutarch.Api.V2 (PMaybeData) import Plutarch.Api.V2 (PMaybeData)
import Plutarch.Extra.Field (pletAll, pletAllC) import Plutarch.Extra.Field (pletAll, pletAllC)
import "liqwid-plutarch-extra" Plutarch.Extra.List (pisSingleton, ptryDeleteFirstBy, ptryFromSingleton)
import Plutarch.Extra.Maybe (pdjust, pdnothing, pmaybeData) import Plutarch.Extra.Maybe (pdjust, pdnothing, pmaybeData)
import Plutarch.Extra.Record (mkRecordConstr, (.&), (.=)) import Plutarch.Extra.Record (mkRecordConstr, (.&), (.=))
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pguardC, pletC, pmatchC) import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pguardC, pletC, pmatchC)
@ -87,7 +87,7 @@ pbatchUpdateInputs = phoistAcyclic $
plam $ \f -> flip pmatch $ \ctxF -> plam $ \f -> flip pmatch $ \ctxF ->
pnull pnull
#$ pfoldr #$ pfoldr
# (pmustDeleteBy # f) # plam (\x -> ptryDeleteFirstBy # (f # x))
# ctxF.stakeOutputDatums # ctxF.stakeOutputDatums
# ctxF.stakeInputDatums # ctxF.stakeInputDatums
@ -387,12 +387,12 @@ pdepositWithdraw = phoistAcyclic $
stakeInputDatum <- stakeInputDatum <-
pletC $ pletC $
ptrace "Single stake input" $ ptrace "Single stake input" $
pfromSingleton # ctxF.stakeInputDatums ptryFromSingleton # ctxF.stakeInputDatums
stakeInputDatumF <- pletAllC stakeInputDatum stakeInputDatumF <- pletAllC stakeInputDatum
let stakeOutputDatum = let stakeOutputDatum =
ptrace "Single stake output" $ ptrace "Single stake output" $
pfromSingleton # ctxF.stakeOutputDatums ptryFromSingleton # ctxF.stakeOutputDatums
---------------------------------------------------------------------------- ----------------------------------------------------------------------------

View file

@ -52,13 +52,7 @@ import Agora.Stake.Redeemers (
ppermitVote, ppermitVote,
pretractVote, pretractVote,
) )
import Agora.Utils ( import Agora.Utils (pisDNothing)
passert,
pisDNothing,
pmapMaybe,
psymbolValueOf',
pvalidatorHashToTokenName,
)
import Plutarch.Api.V1 ( import Plutarch.Api.V1 (
PCredential (PPubKeyCredential, PScriptCredential), PCredential (PPubKeyCredential, PScriptCredential),
PCurrencySymbol, PCurrencySymbol,
@ -79,9 +73,10 @@ import Plutarch.Extra.AssetClass (
passetClass, passetClass,
ptoScottEncoding, ptoScottEncoding,
) )
import Plutarch.Extra.Bool (passert)
import Plutarch.Extra.Field (pletAll, pletAllC) import Plutarch.Extra.Field (pletAll, pletAllC)
import Plutarch.Extra.Functor (PFunctor (pfmap)) import Plutarch.Extra.Functor (PFunctor (pfmap))
import "liqwid-plutarch-extra" Plutarch.Extra.List (pfindJust) import "liqwid-plutarch-extra" Plutarch.Extra.List (pfindJust, pmapMaybe)
import Plutarch.Extra.Maybe ( import Plutarch.Extra.Maybe (
passertPJust, passertPJust,
pfromJust, pfromJust,
@ -93,7 +88,8 @@ import Plutarch.Extra.Maybe (
import Plutarch.Extra.Ord (POrdering (PEQ, PGT, PLT), pcompareBy, pfromOrd) import Plutarch.Extra.Ord (POrdering (PEQ, PGT, PLT), pcompareBy, pfromOrd)
import Plutarch.Extra.ScriptContext ( import Plutarch.Extra.ScriptContext (
pfindTxInByTxOutRef, pfindTxInByTxOutRef,
pfromOutputDatum, ptryFromOutputDatum,
pvalidatorHashToTokenName,
pvalueSpent, pvalueSpent,
) )
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont ( import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (
@ -106,6 +102,7 @@ import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (
import Plutarch.Extra.Value ( import Plutarch.Extra.Value (
passetClassValueOf, passetClassValueOf,
psymbolValueOf, psymbolValueOf,
psymbolValueOf',
) )
import Plutarch.Num (PNum (pnegate)) import Plutarch.Num (PNum (pnegate))
import Plutarch.Unsafe (punsafeCoerce) import Plutarch.Unsafe (punsafeCoerce)
@ -197,7 +194,7 @@ stakePolicy =
datumF <- datumF <-
pletAllC $ pletAllC $
pfromData $ pfromData $
pfromOutputDatum @(PAsData PStakeDatum) ptryFromOutputDatum @(PAsData PStakeDatum)
# outputF.datum # outputF.datum
# txInfoF.datums # txInfoF.datums
@ -277,10 +274,11 @@ mkStakeValidator impl sstSymbol pstClass gstClass =
#$ pfield @"address" #$ pfield @"address"
# validatedInput # validatedInput
let sstName = pvalidatorHashToTokenName #$ pmatch stakeValidatorCredential $ let sstName = pvalidatorHashToTokenName $
\case pmatch stakeValidatorCredential $
PScriptCredential r -> pfield @"_0" # r \case
_ -> perror PScriptCredential r -> pfield @"_0" # r
_ -> perror
sstClass <- pletC $ passetClass # sstSymbol # sstName sstClass <- pletC $ passetClass # sstSymbol # sstName
@ -310,7 +308,7 @@ mkStakeValidator impl sstSymbol pstClass gstClass =
datum = datum =
ptrace "Resolve stake datum" $ ptrace "Resolve stake datum" $
pfromData $ pfromData $
pfromOutputDatum @(PAsData PStakeDatum) ptryFromOutputDatum @(PAsData PStakeDatum)
# txOutF.datum # txOutF.datum
# txInfoF.datums # txInfoF.datums
in passert in passert
@ -439,7 +437,7 @@ mkStakeValidator impl sstSymbol pstClass gstClass =
#== 1 #== 1
proposalDatum = proposalDatum =
pfromData $ pfromData $
pfromOutputDatum @(PAsData PProposalDatum) ptryFromOutputDatum @(PAsData PProposalDatum)
# txOutF.datum # txOutF.datum
# txInfoF.datums # txInfoF.datums
in pif isProposalUTxO (pjust # proposalDatum) pnothing in pif isProposalUTxO (pjust # proposalDatum) pnothing

View file

@ -8,101 +8,22 @@ 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. Plutarch utility functions that should be upstreamed or don't belong anywhere else.
-} -}
module Agora.Utils ( module Agora.Utils (
validatorHashToTokenName,
validatorHashToAddress, validatorHashToAddress,
pltAsData,
withBuiltinPairAsData,
pvalidatorHashToTokenName,
pscriptHashToTokenName,
scriptHashToTokenName,
plistEqualsBy,
pstringIntercalate, pstringIntercalate,
punwords, punwords,
pcurrentTimeDuration,
pdelete,
pdeleteBy,
pmustDeleteBy,
pisSingleton,
pfromSingleton,
pmapMaybe,
PAlternative (..),
ppureIf,
pltBy,
pinsertUniqueBy,
ptryFromRedeemer,
passert,
pisNothing, pisNothing,
pisDNothing, pisDNothing,
psymbolValueOf',
) where ) where
import Plutarch.Api.V1 (
KeyGuarantees (Unsorted),
PPOSIXTime,
PRedeemer,
PValidatorHash,
)
import Plutarch.Api.V1.AssocMap (PMap, plookup)
import Plutarch.Api.V2 ( import Plutarch.Api.V2 (
AmountGuarantees,
PCurrencySymbol,
PMaybeData (PDNothing), PMaybeData (PDNothing),
PScriptHash,
PScriptPurpose,
PTokenName,
PValue,
) )
import Plutarch.Extra.Applicative (PApplicative (ppure))
import Plutarch.Extra.Category (PCategory (pidentity))
import Plutarch.Extra.Functor (PFunctor (PSubcategory, pfmap))
import Plutarch.Extra.Maybe (pjust, pnothing)
import Plutarch.Extra.Ord (PComparator, POrdering (PLT), pcompareBy, pequateBy)
import Plutarch.Extra.Time (PCurrentTime (PCurrentTime))
import Plutarch.Unsafe (punsafeCoerce)
import PlutusLedgerApi.V2 ( import PlutusLedgerApi.V2 (
Address (Address), Address (Address),
Credential (ScriptCredential), Credential (ScriptCredential),
ScriptHash (ScriptHash), ValidatorHash,
TokenName (TokenName),
ValidatorHash (ValidatorHash),
) )
{- Functions which should (probably) not be upstreamed
All of these functions are quite inefficient.
-}
{- | Safely convert a 'ValidatorHash' into a 'TokenName'. This can be useful for tagging
tokens for extra safety.
@since 0.1.0
-}
validatorHashToTokenName :: ValidatorHash -> TokenName
validatorHashToTokenName (ValidatorHash hash) = TokenName hash
{- | Safely convert a 'PValidatorHash' into a 'PTokenName'. This can be useful for tagging
tokens for extra safety.
@since 1.0.0
-}
pvalidatorHashToTokenName :: forall (s :: S). Term s (PValidatorHash :--> PTokenName)
pvalidatorHashToTokenName = phoistAcyclic $ plam punsafeCoerce
{- | Safely convert a 'PScriptHash' into a 'PTokenName'. This can be useful for tagging
tokens for extra safety.
@since 1.0.0
-}
scriptHashToTokenName :: ScriptHash -> TokenName
scriptHashToTokenName (ScriptHash hash) = TokenName hash
{- | Safely convert a 'PScriptHash' into a 'PTokenName'. This can be useful for tagging
tokens for extra safety.
@since 1.0.0
-}
pscriptHashToTokenName :: forall (s :: S). Term s PScriptHash -> Term s PTokenName
pscriptHashToTokenName = punsafeCoerce
{- | Create an 'Address' from a given 'ValidatorHash' with no 'PlutusLedgerApi.V1.Credential.StakingCredential'. {- | Create an 'Address' from a given 'ValidatorHash' with no 'PlutusLedgerApi.V1.Credential.StakingCredential'.
@since 0.1.0 @since 0.1.0
@ -110,62 +31,6 @@ pscriptHashToTokenName = punsafeCoerce
validatorHashToAddress :: ValidatorHash -> Address validatorHashToAddress :: ValidatorHash -> Address
validatorHashToAddress vh = Address (ScriptCredential vh) Nothing validatorHashToAddress vh = Address (ScriptCredential vh) Nothing
{- | Compare two 'PAsData' value, return true if the first one is less than the second one.
@since 0.2.0
-}
pltAsData ::
forall (a :: PType) (s :: S).
(POrd a, PIsData a) =>
Term s (PAsData a :--> PAsData a :--> PBool)
pltAsData = phoistAcyclic $
plam $
\(pfromData -> l) (pfromData -> r) -> l #< r
{- | Extract data stored in a 'PBuiltinPair' and call a function to process it.
@since 0.2.0
-}
withBuiltinPairAsData ::
forall (a :: PType) (b :: PType) (c :: PType) (s :: S).
(PIsData a, PIsData b) =>
(Term s a -> Term s b -> Term s c) ->
Term
s
(PBuiltinPair (PAsData a) (PAsData b)) ->
Term s c
withBuiltinPairAsData f p =
let a = pfromData $ pfstBuiltin # p
b = pfromData $ psndBuiltin # p
in f a b
-- | @since 1.0.0
plistEqualsBy ::
forall
(list1 :: PType -> PType)
(list2 :: PType -> PType)
(a :: PType)
(b :: PType)
(s :: S).
(PIsListLike list1 a, PIsListLike list2 b) =>
Term s ((a :--> b :--> PBool) :--> list1 a :--> list2 b :--> PBool)
plistEqualsBy = phoistAcyclic $
plam $ \eq -> pfix #$ plam $ \self l1 l2 ->
pelimList
( \x xs ->
pelimList
( \y ys ->
-- Avoid comparison if two lists have different length.
self # xs # ys #&& eq # x # y
)
-- l2 is empty, but l1 is not.
(pconstant False)
l2
)
-- l1 is empty, so l2 should be empty as well.
(pnull # l2)
l1
-- | @since 1.0.0 -- | @since 1.0.0
pstringIntercalate :: pstringIntercalate ::
forall (s :: S). forall (s :: S).
@ -183,225 +48,6 @@ punwords ::
Term s PString Term s PString
punwords = pstringIntercalate " " punwords = pstringIntercalate " "
-- | @since 1.0.0
pcurrentTimeDuration ::
forall (s :: S).
Term
s
( PCurrentTime
:--> PPOSIXTime
)
pcurrentTimeDuration = phoistAcyclic $
plam $
flip pmatch $
\(PCurrentTime lb ub) -> ub - lb
{- | / O(n) /. Remove the first occurance of a value from the given list.
@since 1.0.0
-}
pdelete ::
forall (a :: PType) (list :: PType -> PType) (s :: S).
(PEq a, PIsListLike list a) =>
Term s (a :--> list a :--> PMaybe (list a))
pdelete = phoistAcyclic $ pdeleteBy # plam (#==)
-- | @since 1.0.0
pdeleteBy ::
forall (a :: PType) (list :: PType -> PType) (s :: S).
(PIsListLike list a) =>
Term s ((a :--> a :--> PBool) :--> a :--> list a :--> PMaybe (list a))
pdeleteBy = phoistAcyclic $
plam $ \f' x -> plet (f' # x) $ \f ->
precList
( \self h t ->
pif
(f # h)
(pjust # t)
(pfmap # (pcons # h) # (self # t))
)
(const pnothing)
-- | @since 1.0.0
pmustDeleteBy ::
forall (a :: PType) (list :: PType -> PType) (s :: S).
(PIsListLike list a) =>
Term s ((a :--> a :--> PBool) :--> a :--> list a :--> list a)
pmustDeleteBy = phoistAcyclic $
plam $ \f' x -> plet (f' # x) $ \f ->
precList
( \self h t ->
pif
(f # h)
t
(pcons # h #$ self # t)
)
(const $ ptraceError "Cannot delete element")
{- | / O(1) /.Return true if the given list has only one element.
@since 1.0.0
-}
pisSingleton ::
forall (a :: PType) (list :: PType -> PType) (s :: S).
(PIsListLike list a) =>
Term s (list a :--> PBool)
pisSingleton =
phoistAcyclic $
precList
(\_ _ t -> pnull # t)
(const $ pconstant False)
{- Throws an error if the given list contains zero or more than one elements.
Otherwise returns the only element.
@since 1.0.0
-}
pfromSingleton ::
forall (a :: PType) (list :: PType -> PType) (s :: S).
(PIsListLike list a) =>
Term s (list a :--> a)
pfromSingleton =
phoistAcyclic $
precList
( \_ h t ->
pif
(pnull # t)
h
(ptraceError "More than one element")
)
(const $ ptraceError "Empty list")
{- | A version of 'pmap' which can throw out elements and change the list type
along the way.
@since 1.0.0
-}
pmapMaybe ::
forall
(listO :: PType -> PType)
(b :: PType)
(listI :: PType -> PType)
(a :: PType)
(s :: S).
(PIsListLike listI a, PIsListLike listO b) =>
Term s ((a :--> PMaybe b) :--> listI a :--> listO b)
pmapMaybe = phoistAcyclic $
plam $ \f ->
precList
( \self h t ->
pmatch
(f # h)
( \case
PJust x -> pcons # x
PNothing -> pidentity
)
# (self # t)
)
(const pnil)
infixl 3 #<|>
-- | @since 1.0.0
class (PApplicative f) => PAlternative (f :: PType -> PType) where
(#<|>) ::
forall (a :: PType) (s :: S).
(PSubcategory f a) =>
Term s (f a :--> f a :--> f a)
pempty ::
forall (a :: PType) (s :: S).
(PSubcategory f a) =>
Term s (f a)
-- | @since 1.0.0
instance PAlternative PMaybe where
(#<|>) = phoistAcyclic $
plam $ \a b -> pmatch a $ \case
PNothing -> b
PJust _ -> a
pempty = pnothing
-- | @since 1.0.0
ppureIf ::
forall
(f :: PType -> PType)
(a :: PType)
(s :: S).
(PAlternative f, PSubcategory f a) =>
Term s (PBool :--> a :--> f a)
ppureIf = phoistAcyclic $
plam $ \cond x ->
pif
cond
(ppure # x)
pempty
{- | Less then check using a `PComparator`.
@ since 1.0.0
-}
pltBy ::
forall (a :: PType) (s :: S).
Term
s
( PComparator a
:--> a
:--> a
:--> PBool
)
pltBy = phoistAcyclic $
plam $ \c x y ->
pcompareBy # c # x # y #== pcon PLT
-- | @since 1.0.0
pinsertUniqueBy ::
forall (list :: PType -> PType) (a :: PType) (s :: S).
(PIsListLike list a) =>
Term s (PComparator a :--> a :--> list a :--> list a)
pinsertUniqueBy = phoistAcyclic $
plam $ \c x ->
let lt = pltBy # c
eq = pequateBy # c
in precList
( \self h t ->
let ensureUniqueness =
pif
(eq # x # h)
(ptraceError "inserted value already exists")
next =
pif
(lt # x # h)
(pcons # x #$ pcons # h # t)
(pcons # h #$ self # t)
in ensureUniqueness next
)
(const $ psingleton # x)
-- | @since 1.0.0
ptryFromRedeemer ::
forall (r :: PType) (s :: S).
(PTryFrom PData r) =>
Term
s
( PScriptPurpose
:--> PMap 'Unsorted PScriptPurpose PRedeemer
:--> PMaybe r
)
ptryFromRedeemer = phoistAcyclic $
plam $ \p m ->
pfmap
# plam (flip ptryFrom fst . pto)
# (plookup # p # m)
-- | @since 1.0.0
passert ::
forall (a :: PType) (s :: S).
Term s PString ->
Term s PBool ->
Term s a ->
Term s a
passert msg cond x = pif cond x $ ptraceError msg
-- | @since 1.0.0 -- | @since 1.0.0
pisNothing :: pisNothing ::
forall (a :: PType) (s :: S). forall (a :: PType) (s :: S).
@ -421,46 +67,3 @@ pisDNothing = phoistAcyclic $
flip pmatch $ \case flip pmatch $ \case
PDNothing _ -> pconstant True PDNothing _ -> pconstant True
_ -> pconstant False _ -> pconstant False
{- | Get the negative and positive amount of a particular 'CurrencySymbol', and
return nothing if it doesn't exist in the value.
@since 1.0.0
-}
psymbolValueOf' ::
forall
(keys :: KeyGuarantees)
(amounts :: AmountGuarantees)
(s :: S).
Term
s
( PCurrencySymbol
:--> PValue keys amounts
:--> PMaybe
( PPair
-- Positive amount
PInteger
-- Negative amount
PInteger
)
)
psymbolValueOf' = phoistAcyclic $
plam $ \sym value ->
let tnMap = plookup # sym # pto value
f =
plam $
( pfoldr
# plam
( \x r ->
let q = pfromData $ psndBuiltin # x
in pmatch r $ \(PPair p n) ->
pif
(0 #< q)
(pcon $ PPair (p + q) n)
(pcon $ PPair p (n + q))
)
# pcon (PPair 0 0)
#
)
. pto
in pfmap # f # tnMap