check if the UTXO carries a valid datum while minting GST

This commit is contained in:
fanghr 2022-05-03 19:44:46 +08:00
parent 41da2dd534
commit 15fd232874
No known key found for this signature in database
GPG key ID: 35CD9A71CD5D5870
2 changed files with 44 additions and 4 deletions

View file

@ -20,6 +20,7 @@ module Agora.Governor (
-- * Utilities
pgetNextProposalId,
getNextProposalId,
governorDatumValid,
) where
--------------------------------------------------------------------------------
@ -32,7 +33,7 @@ import Generics.SOP (Generic, I (I))
import Agora.Proposal (
PProposalId (..),
PProposalThresholds,
PProposalThresholds (..),
ProposalId (ProposalId),
ProposalThresholds,
)
@ -46,7 +47,8 @@ import Plutarch.DataRepr (
PIsDataReprInstances (PIsDataReprInstances),
)
import Plutarch.Lift (PConstantDecl, PUnsafeLiftDecl (..))
import Plutarch.SafeMoney (Tagged (..))
import Plutarch.Monadic qualified as P
import Plutarch.SafeMoney (Tagged (..), puntag)
import Plutarch.TryFrom (PTryFrom (..))
import Plutarch.Unsafe (punsafeCoerce)
@ -161,3 +163,25 @@ pgetNextProposalId = phoistAcyclic $ plam $ \(pto -> pid) -> pcon $ PProposalId
-- | Get next proposal id.
getNextProposalId :: ProposalId -> ProposalId
getNextProposalId (ProposalId pid) = ProposalId $ pid + 1
--------------------------------------------------------------------------------
governorDatumValid :: Term s (PGovernorDatum :--> PBool)
governorDatumValid = phoistAcyclic $
plam $ \datum -> P.do
thresholds <-
pletFields @'["execute", "draft", "vote"] $
pfield @"proposalThresholds" # datum
execute <- plet $ puntag thresholds.execute
draft <- plet $ puntag thresholds.draft
vote <- plet $ puntag thresholds.vote
foldr1
(#&&)
[ ptraceIfFalse "Execute threshold larger than 0" $ 0 #<= execute
, ptraceIfFalse "Draft threshold larger than 0" $ 0 #<= draft
, ptraceIfFalse "Vote threshold larger than 0" $ 0 #<= vote
, ptraceIfFalse "Draft threshold larger than vote threshold" $ draft #<= vote
, ptraceIfFalse "Execute threshold larger than vote threshold" $ vote #< execute
]

View file

@ -42,6 +42,7 @@ import Agora.Governor (
Governor (gstOutRef, gtClassRef, maximumCosigners),
PGovernorDatum (PGovernorDatum),
PGovernorRedeemer (PCreateProposal, PMintGATs, PMutateGovernor),
governorDatumValid,
pgetNextProposalId,
)
import Agora.Proposal (
@ -157,6 +158,7 @@ import Plutus.V1.Ledger.Value (
- The UTXO referenced in the parameter is spent in the transaction.
- Exactly one GST is minted.
- Ensure the token name is empty.
- Said UTXO should carry a valid 'Agora.Governor.GovernorDatum'.
NOTE: It's user's responsibility to make sure the token is sent to the corresponding governor validator.
We /can't/ really check this in the policy, otherwise we create a cyclic reference issue.
@ -170,7 +172,7 @@ governorPolicy gov =
let ownAssetClass = passetClass # ownSymbol # pconstant ""
txInfo = pfromData $ pfield @"txInfo" # ctx'
txInfoF <- pletFields @'["mint", "inputs"] txInfo
txInfoF <- pletFields @'["mint", "inputs", "outputs", "datums"] txInfo
passert "Referenced utxo should be spent" $
pisUTXOSpent # oref # txInfoF.inputs
@ -179,7 +181,21 @@ governorPolicy gov =
psymbolValueOf # ownSymbol # txInfoF.mint #== 1
#&& passetClassValueOf # txInfoF.mint # ownAssetClass #== 1
popaque (pconstant ())
govOutput <-
plet $
mustBePJust
# "Governor output not found"
#$ pfind
# plam
( \((pfield @"value" #) . pfromData -> value) ->
psymbolValueOf # ownSymbol # value #== 1
)
# pfromData txInfoF.outputs
let datumHash = pfield @"datumHash" # pfromData govOutput
datum = mustFindDatum' @PGovernorDatum # datumHash # txInfoF.datums
popaque $ governorDatumValid # datum
{- | Validator for Governors.