Treasury Withdrawal Effect

ensures exact number of outputs, Haskell-level datum
This commit is contained in:
Seungheon Oh 2022-04-12 19:38:33 -05:00 committed by Seungheon Oh
parent fecbf66782
commit 2fc54b3fc5
No known key found for this signature in database
GPG key ID: 9B0E12D357369B66

View file

@ -1,12 +1,14 @@
{-# LANGUAGE TemplateHaskell #-}
{- |
Module : Agora.Effect.TreasuryWithdrawal
Maintainer : seungheon.ooh@gmail.com
Description: An Effect that withdraws treasury deposit
-}
module Agora.Effect.TreasuryWithdrawal (PTreasuryWithdrawalDatum, treasuryWithdrawalValidator) where
module Agora.Effect.TreasuryWithdrawal (TreasuryWithdrawalDatum, PTreasuryWithdrawalDatum, treasuryWithdrawalValidator) where
import GHC.Generics qualified as GHC
import Generics.SOP (Generic, I (I))
import Generics.SOP ( I(I), Generic )
import Agora.Effect (makeEffect)
import Agora.Utils (passert)
@ -18,9 +20,22 @@ import Plutarch.Api.V1 (
PValue,
ptuple,
)
import Plutarch.DataRepr (PDataFields, PIsDataReprInstances (..))
import Plutarch.DataRepr
( PDataFields,
PIsDataReprInstances(..),
DerivePConstantViaData(..) )
import Plutarch.Lift ( PUnsafeLiftDecl(..) )
import Plutarch.Monadic qualified as P
import Plutus.V1.Ledger.Value (CurrencySymbol)
import Plutus.V1.Ledger.Credential ( Credential )
import Plutus.V1.Ledger.Value ( CurrencySymbol, Value )
import PlutusTx qualified
data TreasuryWithdrawalDatum = TreasuryWithdrawalDatum {receivers :: [(Credential, Value)]}
deriving stock (Show, GHC.Generic)
deriving anyclass (Generic)
PlutusTx.makeLift ''TreasuryWithdrawalDatum
PlutusTx.unstableMakeIsData ''TreasuryWithdrawalDatum
data PTreasuryWithdrawalDatum (s :: S)
= PTreasuryWithdrawalDatum
@ -36,10 +51,19 @@ data PTreasuryWithdrawalDatum (s :: S)
(PlutusType, PIsData, PDataFields)
via PIsDataReprInstances PTreasuryWithdrawalDatum
instance PUnsafeLiftDecl PTreasuryWithdrawalDatum where
type PLifted PTreasuryWithdrawalDatum = TreasuryWithdrawalDatum
deriving via
(DerivePConstantViaData TreasuryWithdrawalDatum PTreasuryWithdrawalDatum)
instance
(PConstant TreasuryWithdrawalDatum)
treasuryWithdrawalValidator :: forall {s :: S}. CurrencySymbol -> Term s PValidator
treasuryWithdrawalValidator currSymbol = makeEffect currSymbol $
\_cs (_datum :: Term _ PTreasuryWithdrawalDatum) _txOutRef _txInfo -> P.do
let outputs =
receivers <- plet $ pfromData $ pfield @"receivers" # _datum
txInfo <- pletFields @'["outputs"] _txInfo
let outputValues =
pmap
# plam
( \_out -> P.do
@ -47,15 +71,17 @@ treasuryWithdrawalValidator currSymbol = makeEffect currSymbol $
cred <- pletFields @'["credential"] $ pfromData out.address
pdata $ ptuple # cred.credential # out.value
)
#$ pfield @"outputs"
# _txInfo
recivers = pfromData $ pfield @"receivers" # _datum
checkOutputs =
#$ txInfo.outputs
outputContentMatchesRecivers =
pall # plam id #$ pmap
# plam
( \_out -> P.do
pelem # _out # outputs
)
#$ recivers
passert "Transaction output does not match receivers" checkOutputs
# plam (\_out -> pelem # _out # outputValues)
#$ receivers
outputNumberMatchesRecivers = plength # receivers #== plength # (pfromData txInfo.outputs)
outputIsNotPayingToEffect = pconstant True -- How to check if it's not paying to effect itself?
passert "Transaction output does not match receivers"
$ outputContentMatchesRecivers
#&& outputNumberMatchesRecivers
#&& outputIsNotPayingToEffect
popaque $ pconstant ()