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 76d1454692
commit b3b057cfb8

View file

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