prevent ambiguous stake inputs while creating proposals

This commit is contained in:
Hongrui Fang 2022-10-05 00:10:26 +08:00
parent 224a49abb3
commit e9ad834b6e

View file

@ -48,7 +48,7 @@ import Agora.Stake (
), ),
pstakeLocked, pstakeLocked,
) )
import Agora.Utils (pdeleteBy, pfromSingleton) import Agora.Utils (pdeleteBy, pfromSingleton, pisSingleton)
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)
@ -149,7 +149,7 @@ pvoteHelper ::
forall (s :: S). forall (s :: S).
Term Term
s s
( ( PProposalContext ( ( PStakeRedeemerHandlerContext
:--> PBuiltinList (PAsData PProposalLock) :--> PBuiltinList (PAsData PProposalLock)
:--> PBuiltinList (PAsData PProposalLock) :--> PBuiltinList (PAsData PProposalLock)
) )
@ -157,8 +157,6 @@ pvoteHelper ::
) )
pvoteHelper = phoistAcyclic $ pvoteHelper = phoistAcyclic $
plam $ \valProposalCtx ctx -> unTermCont $ do plam $ \valProposalCtx ctx -> unTermCont $ do
ctxF <- pmatchC ctx
pguardC "Owner or delegate signs this transaction" $ pguardC "Owner or delegate signs this transaction" $
pisSignedBy # pconstant True # ctx pisSignedBy # pconstant True # ctx
@ -166,7 +164,7 @@ pvoteHelper = phoistAcyclic $
-- that this is not abused. -- that this is not abused.
pguardC "Correct outputs" $ pguardC "Correct outputs" $
ponlyLocksUpdated # (valProposalCtx # ctxF.proposalContext) # ctx ponlyLocksUpdated # (valProposalCtx # ctx) # ctx
pure $ pconstant () pure $ pconstant ()
@ -189,26 +187,34 @@ paddNewLock = phoistAcyclic $
@since 1.0.0 @since 1.0.0
-} -}
ppermitVote :: forall (s :: S). Term s PStakeRedeemerHandler ppermitVote :: forall (s :: S). Term s PStakeRedeemerHandler
ppermitVote = pvoteHelper #$ phoistAcyclic $ ppermitVote = phoistAcyclic $
plam $ pvoteHelper #$ phoistAcyclic $
flip pmatch $ \case plam $ \ctx -> unTermCont $ do
ctxF <- pmatchC ctx
let withOnlyOneStakeInput =
plam $ \lock -> unTermCont $ do
pguardC "Only one stake input allowed" $
pisSingleton # ctxF.stakeInputDatums
pure lock
pure $
paddNewLock #$ pmatch ctxF.proposalContext $ \case
PSpendProposal pid _ r -> pmatch r $ \case PSpendProposal pid _ r -> pmatch r $ \case
PVote ((pfromData . (pfield @"resultTag" #)) -> voteFor) -> PVote ((pfromData . (pfield @"resultTag" #)) -> voteFor) ->
let newLock =
mkRecordConstr mkRecordConstr
PVoted PVoted
( #votedOn .= pdata pid ( #votedOn .= pdata pid
.& #votedFor .= pdata voteFor .& #votedFor .= pdata voteFor
) )
in paddNewLock # newLock
_ -> ptraceError "Expected Vote" _ -> ptraceError "Expected Vote"
PNewProposal pid -> PNewProposal pid ->
let newLock = withOnlyOneStakeInput
mkRecordConstr #$ mkRecordConstr
PCreated PCreated
( #created .= pdata pid ( #created .= pdata pid
) )
in paddNewLock # newLock
_ -> ptraceError "Expected proposal" _ -> ptraceError "Expected proposal"
{- | Remove stake locks with the proposal id given the list of existing locks. {- | Remove stake locks with the proposal id given the list of existing locks.
@ -237,9 +243,11 @@ premoveLocks = phoistAcyclic $
@since 1.0.0 @since 1.0.0
-} -}
pretractVote :: forall (s :: S). Term s PStakeRedeemerHandler pretractVote :: forall (s :: S). Term s PStakeRedeemerHandler
pretractVote = pvoteHelper #$ phoistAcyclic $ pretractVote = phoistAcyclic $
pvoteHelper #$ phoistAcyclic $
plam $ plam $
flip pmatch $ \case flip pmatch $ \ctxF ->
pmatch ctxF.proposalContext $ \case
PSpendProposal pid s r -> pmatch r $ \case PSpendProposal pid s r -> pmatch r $ \case
PUnlock _ -> PUnlock _ ->
let allowRemovingCreatorLock = let allowRemovingCreatorLock =