Treasury Withdrawal Effect: Only check treasury inputs

Tried to make it so that its only checking treasury inputs when
checking if transaction is correctly returning the remainders to treasury.
This commit is contained in:
Seungheon Oh 2022-04-18 13:59:59 -05:00
parent c9adf02614
commit 4328fa1ba9

View file

@ -13,16 +13,17 @@ import GHC.Generics qualified as GHC
import Generics.SOP (Generic, I (I)) import Generics.SOP (Generic, I (I))
import Agora.Effect (makeEffect) import Agora.Effect (makeEffect)
import Agora.Utils ( paddValue, passert ) import Agora.Utils (findTxOutByTxOutRef, paddValue, passert)
import Plutarch (popaque) import Plutarch (popaque)
import Plutarch.Api.V1 import Plutarch.Api.V1 (
( PCredential, PCredential,
PValue, PTuple,
PTxOut(PTxOut), PTxInInfo (PTxInInfo),
PTxInInfo(PTxInInfo), PTxOut (PTxOut),
PTuple, PValidator,
ptuple, PValue,
PValidator ) ptuple,
)
import Plutarch.DataRepr ( import Plutarch.DataRepr (
DerivePConstantViaData (..), DerivePConstantViaData (..),
@ -79,9 +80,11 @@ It can be more flexiable over...
-} -}
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
receivers <- plet $ pfromData $ pfield @"receivers" # datum' receivers <- plet $ pfromData $ pfield @"receivers" # datum'
txInfo <- pletFields @'["outputs", "inputs"] txInfo' txInfo <- pletFields @'["outputs", "inputs"] txInfo'
PJust txOut <- pmatch $ findTxOutByTxOutRef # txOutRef' # pfromData txInfo'
effInput <- pletFields @'["address", "value"] $ txOut
let outputValues = let outputValues =
pmap pmap
# plam # plam
@ -94,37 +97,58 @@ treasuryWithdrawalValidator currSymbol = makeEffect currSymbol $
outputContentMatchesRecivers = outputContentMatchesRecivers =
pall # plam (\out -> pelem # out # outputValues) pall # plam (\out -> pelem # out # outputValues)
#$ receivers #$ receivers
sumValues = sumValues =
pfoldr pfoldr
# plam # plam
( \((pfield @"_1" #) . pfromData -> x) y -> P.do ( \((pfield @"_1" #) . pfromData -> x) y -> P.do
paddValue # (pfromData x) # y paddValue # pfromData x # y
) )
# (pconstant (mempty :: Value)) # pconstant (mempty :: Value)
inputCred = inputCred =
pmap pmap
# plam (\inInfo -> P.do # plam
PTxInInfo inInfo' <- pmatch $ pfromData inInfo ( \inInfo -> P.do
PTxOut out <- pmatch $ pfromData $ pfield @"resolved" # inInfo' PTxInInfo inInfo' <- pmatch $ pfromData inInfo
let addr = pfromData $ pfield @"address" # out PTxOut out <- pmatch $ pfromData $ pfield @"resolved" # inInfo'
pfield @"credential" # addr) let addr = pfromData $ pfield @"address" # out
pfield @"credential" # addr
)
# pfromData txInfo.inputs # pfromData txInfo.inputs
totalInput = totalTreasuryInputs =
pfoldr pfoldr
# plam (\x' y -> P.do # plam
PTxInInfo x <- pmatch $ pfromData x' ( \x' y -> P.do
PTxOut out <- pmatch $ pfromData $ pfield @"resolved" # x PTxInInfo x <- pmatch $ pfromData x'
paddValue # (pfromData $ pfield @"value" # out) # y) PTxOut out <- pmatch $ pfromData $ pfield @"resolved" # x
# (pconstant (mempty :: Value)) -- only take ones from treasury
pif
(effInput.address #== pfield @"address" # out)
(paddValue # pfromData (pfield @"value" # out) # y)
y
)
# pconstant (mempty :: Value)
# pfromData txInfo.inputs # pfromData txInfo.inputs
sumOutputsToInputAddr = sumValues #$ sumOutputsToTreasury =
pfilter sumValues
# plam (\((pfield @"_0" #) . pfromData -> addr) -> pelem # (addr) # inputCred) # outputValues #$ pfilter
sumReceivers = sumValues # receivers # plam
-- TODO: Probably need to check/exclude the effect input... ( \((pfield @"_0" #) . pfromData -> addr) ->
excessShouldBePaidToInputs = pdata (paddValue # sumReceivers # sumOutputsToInputAddr) #== pdata totalInput pelem # addr # inputCred
#&& pnot # (addr #== pfield @"credential" # effInput.address)
)
# outputValues
-- TODO: Probably need to check/exclude the effect input...
excessShouldBePaidToInputs =
pdata (paddValue # (sumValues # receivers) # sumOutputsToTreasury) #== pdata totalTreasuryInputs
shouldNotPayToEffect =
pnot #$ pany
# plam
( \x ->
effInput.address #== pfield @"address" # pfromData x
)
# pfromData txInfo.outputs
passert "Transaction output does not match receivers" outputContentMatchesRecivers passert "Transaction output does not match receivers" outputContentMatchesRecivers
passert "Remainders should be returned to the treasury" excessShouldBePaidToInputs passert "Transaction should not pay to effects" shouldNotPayToEffect
passert "Remainders should be returned to the treasury" excessShouldBePaidToInputs -- We might not need this.
popaque $ pconstant () popaque $ pconstant ()