began reworking treasury
This commit is contained in:
parent
fbf87a9165
commit
ade66fdbd0
2 changed files with 80 additions and 84 deletions
|
|
@ -1,3 +1,5 @@
|
||||||
|
{-# OPTIONS_GHC -Wwarn #-}
|
||||||
|
|
||||||
{- |
|
{- |
|
||||||
Module: Agora.Treasury
|
Module: Agora.Treasury
|
||||||
Maintainer: jack@mlabs.city
|
Maintainer: jack@mlabs.city
|
||||||
|
|
@ -28,6 +30,7 @@ import Plutarch.DataRepr (
|
||||||
PIsDataReprInstances (PIsDataReprInstances),
|
PIsDataReprInstances (PIsDataReprInstances),
|
||||||
)
|
)
|
||||||
import Plutarch.Monadic qualified as P
|
import Plutarch.Monadic qualified as P
|
||||||
|
import Agora.Utils (pisValueSubset)
|
||||||
|
|
||||||
{- | Validator ensuring that transactions consuming the treasury
|
{- | Validator ensuring that transactions consuming the treasury
|
||||||
do so in a valid manner.
|
do so in a valid manner.
|
||||||
|
|
@ -41,92 +44,27 @@ treasuryV ::
|
||||||
:--> PUnit
|
:--> PUnit
|
||||||
)
|
)
|
||||||
treasuryV = plam $ \d r ctx' -> P.do
|
treasuryV = plam $ \d r ctx' -> P.do
|
||||||
-- Load txInfo and purpose fields from script context.
|
|
||||||
ctx <- pletFields @["txInfo", "purpose"] ctx'
|
|
||||||
|
|
||||||
-- Extract txInfo.
|
|
||||||
PTxInfo txInfo' <- pmatch $ pfromData ctx.txInfo
|
|
||||||
|
|
||||||
-- Pattern match on type of treasury redeemer.
|
|
||||||
pmatch (pfromData r) $ \case
|
pmatch (pfromData r) $ \case
|
||||||
-- Treasury is merely being witnessed. It's datum and value
|
-- Redeemer seeking to alter treasury parameters. Must ensure
|
||||||
-- must be unchanged.
|
-- a valid GAT is burned in the transaction.
|
||||||
PWitnessTreasury _ -> P.do
|
PAlterTrParams _ ->
|
||||||
txInfo <- pletFields @'["inputs", "outputs", "data"] txInfo'
|
ptraceError "Altering treasury parameters is not currently supported."
|
||||||
|
-- Redeemer for all other treasury actions. Must ensure datum
|
||||||
|
-- is unchanged and no value has been removed from the
|
||||||
|
-- treasury.
|
||||||
|
PRedeemTreasury _ -> P.do
|
||||||
|
-- Amount of value treasury has before transaction.
|
||||||
|
let valueTrIn = undefined
|
||||||
|
|
||||||
-- Get datum hash of datum supplied to validator.
|
-- Amount of value treasury has after transaction.
|
||||||
let dat = pfield @"data" # txInfo'
|
let valueTrOut = undefined
|
||||||
dH = getTrDatumHash # d # dat
|
|
||||||
|
|
||||||
-- Get inputs in TxOut form.
|
let vOutExceedsVIn = pisValueSubset # valueTrIn # valueTrOut
|
||||||
let inputs = txInfo.inputs
|
|
||||||
rs = pmap # toResolved # inputs
|
|
||||||
|
|
||||||
-- Find the value the treasury had before being spent.
|
|
||||||
let valueIn = getValAtDHash # dH # rs
|
|
||||||
|
|
||||||
-- Find the value the treasury has after being spent.
|
|
||||||
let outputs = txInfo.outputs
|
|
||||||
valueOut = getValAtDHash # dH # outputs
|
|
||||||
|
|
||||||
-- If the value in equals the value out, validate the
|
|
||||||
-- transaction. Otherwise, fail.
|
|
||||||
pif
|
pif
|
||||||
(valueIn #== valueOut)
|
(vOutExceedsVIn)
|
||||||
(pconstant ())
|
(pconstant ())
|
||||||
$ ptraceError "Treasury is altered when witnessing transaction"
|
(ptraceError "Value has been illegally deducted from treasury.")
|
||||||
|
|
||||||
-- Treasury is receiving amount of funds specified in the
|
|
||||||
-- redeemer. It's datum must be unchanged but it's value
|
|
||||||
-- must be increased by the specified amount.
|
|
||||||
PReceiveFunds _ -> P.do
|
|
||||||
pconstant ()
|
|
||||||
|
|
||||||
{- | Plutarch level function that, given a treasury datum and a
|
|
||||||
list of the transaction's data, will find its hash.
|
|
||||||
-}
|
|
||||||
getTrDatumHash ::
|
|
||||||
Term
|
|
||||||
s
|
|
||||||
( PAsData PTreasuryDatum
|
|
||||||
:--> PBuiltinList (PAsData (PTuple PDatumHash PDatum))
|
|
||||||
:--> PDatumHash
|
|
||||||
)
|
|
||||||
getTrDatumHash = plam $ \d l -> P.do
|
|
||||||
let t = phead #$ pfilter # (matchDatums # d) # l
|
|
||||||
pfield @"_0" # t
|
|
||||||
where
|
|
||||||
matchDatums ::
|
|
||||||
Term
|
|
||||||
s
|
|
||||||
( PAsData PTreasuryDatum
|
|
||||||
:--> PAsData (PTuple PDatumHash PDatum)
|
|
||||||
:--> PBool
|
|
||||||
)
|
|
||||||
matchDatums = plam $ \d t' ->
|
|
||||||
let t = pfield @"_1" # t'
|
|
||||||
in pforgetData d #== pforgetData t
|
|
||||||
|
|
||||||
-- | Get the "resolved" field of a TxInInfo.
|
|
||||||
toResolved :: Term s (PAsData PTxInInfo :--> PAsData PTxOut)
|
|
||||||
toResolved = plam $ \txIn -> pfield @"resolved" # txIn
|
|
||||||
|
|
||||||
-- | Gets the value kept at a given datum hash.
|
|
||||||
getValAtDHash ::
|
|
||||||
Term
|
|
||||||
s
|
|
||||||
( PDatumHash
|
|
||||||
:--> PBuiltinList (PAsData PTxOut)
|
|
||||||
:--> PAsData PValue
|
|
||||||
)
|
|
||||||
getValAtDHash = plam $ \dh outs -> P.do
|
|
||||||
let matchingOut = phead #$ pfilter # (matchHashes # dh) # outs
|
|
||||||
pfield @"value" # matchingOut
|
|
||||||
where
|
|
||||||
matchHashes :: Term s (PDatumHash :--> PAsData PTxOut :--> PBool)
|
|
||||||
matchHashes = plam $ \dh out' -> P.do
|
|
||||||
PDJust dh' <- pmatch $ pfield @"datumHash" # pfromData out'
|
|
||||||
dh #== pfield @"_0" # dh'
|
|
||||||
|
|
||||||
{- | Plutarch level type representing datum of the treasury.
|
{- | Plutarch level type representing datum of the treasury.
|
||||||
Contains:
|
Contains:
|
||||||
|
|
@ -153,10 +91,10 @@ newtype PTreasuryDatum (s :: S)
|
||||||
treasury.
|
treasury.
|
||||||
-}
|
-}
|
||||||
data PTreasuryRedeemer (s :: S)
|
data PTreasuryRedeemer (s :: S)
|
||||||
= -- | Receive funds and place them in the treasury.
|
= -- | TODO: will allow the burning of GATs to alter Treasury params.
|
||||||
PReceiveFunds (Term s (PDataRecord '["_0" ':= PValue]))
|
PAlterTrParams (Term s (PDataRecord '[]))
|
||||||
| -- | Serve as a witness for any transaction. Must remain unaltered.
|
| -- | All other treasury actions. Value must not decrease.
|
||||||
PWitnessTreasury (Term s (PDataRecord '[]))
|
PRedeemTreasury (Term s (PDataRecord '[]))
|
||||||
deriving stock (GHC.Generic)
|
deriving stock (GHC.Generic)
|
||||||
deriving anyclass (Generic, PIsDataRepr)
|
deriving anyclass (Generic, PIsDataRepr)
|
||||||
deriving
|
deriving
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
{-# OPTIONS_GHC -Wwarn #-}
|
||||||
|
|
||||||
{- |
|
{- |
|
||||||
Module : Agora.Utils
|
Module : Agora.Utils
|
||||||
Maintainer : emi@haskell.fyi
|
Maintainer : emi@haskell.fyi
|
||||||
|
|
@ -22,6 +24,7 @@ module Agora.Utils (
|
||||||
pfindTxInByTxOutRef,
|
pfindTxInByTxOutRef,
|
||||||
psingletonValue,
|
psingletonValue,
|
||||||
pfindMap,
|
pfindMap,
|
||||||
|
pisValueSubset,
|
||||||
|
|
||||||
-- * Functions which should (probably) not be upstreamed
|
-- * Functions which should (probably) not be upstreamed
|
||||||
anyOutput,
|
anyOutput,
|
||||||
|
|
@ -50,6 +53,8 @@ import Plutarch.Api.V1 (
|
||||||
PTxOutRef,
|
PTxOutRef,
|
||||||
PValue (PValue),
|
PValue (PValue),
|
||||||
)
|
)
|
||||||
|
import Plutarch.Api.V1.Tuple (ptupleFromBuiltin)
|
||||||
|
import Plutarch.Bool (pand)
|
||||||
import Plutarch.Builtin (ppairDataBuiltin)
|
import Plutarch.Builtin (ppairDataBuiltin)
|
||||||
import Plutarch.Internal (punsafeCoerce)
|
import Plutarch.Internal (punsafeCoerce)
|
||||||
import Plutarch.Monadic qualified as P
|
import Plutarch.Monadic qualified as P
|
||||||
|
|
@ -255,6 +260,59 @@ pfindTxInByTxOutRef = phoistAcyclic $
|
||||||
)
|
)
|
||||||
#$ (pfield @"inputs" # txInfo)
|
#$ (pfield @"inputs" # txInfo)
|
||||||
|
|
||||||
|
-- | Determines if a value is a subset of another.
|
||||||
|
pisValueSubset :: Term s (PValue :--> PValue :--> PBool)
|
||||||
|
pisValueSubset = plam $ \v0 _v1 -> P.do
|
||||||
|
-- v0Map :: Term s (PMap PCurrencySymbol (PMap PTokenName PInteger))
|
||||||
|
PValue v0Map <- pmatch v0
|
||||||
|
|
||||||
|
-- v0BuiltinMap :: Term s (PBuiltinMap k v)
|
||||||
|
PMap v0BuiltinMap <- pmatch v0Map
|
||||||
|
|
||||||
|
-- ks0 :: Term s (PBuiltinList PCurrencySymbol)
|
||||||
|
let ks0 = pmap # pfstBuiltin # v0BuiltinMap
|
||||||
|
pconstant True
|
||||||
|
|
||||||
|
-- | Determines if a PTokenName/PInteger pmap is a subset of another.
|
||||||
|
pisTnISubset ::
|
||||||
|
Term
|
||||||
|
s
|
||||||
|
( PMap PTokenName PInteger
|
||||||
|
:--> PMap PTokenName PInteger
|
||||||
|
:--> PBool
|
||||||
|
)
|
||||||
|
pisTnISubset = plam $ \m0 m1 -> P.do
|
||||||
|
-- m0BuiltinMap :: Term s (PBuiltinMap PTokenName PInteger)
|
||||||
|
PMap m0BuiltinMap <- pmatch m0
|
||||||
|
|
||||||
|
-- ks0 :: Term s (PBuiltinList PTokenName)
|
||||||
|
let ks0 = pmap # pfstBuiltin # m0BuiltinMap
|
||||||
|
pconstant True
|
||||||
|
|
||||||
|
pcompareKeysForEq ::
|
||||||
|
Term
|
||||||
|
s
|
||||||
|
( PBuiltinList k
|
||||||
|
:--> PMap k v
|
||||||
|
:--> PMap k v
|
||||||
|
:--> PBool
|
||||||
|
)
|
||||||
|
pcompareKeysForEq = plam $ \ks m0' m1' -> P.do
|
||||||
|
PMap m0 <- m0'
|
||||||
|
PMap m1 <- m1'
|
||||||
|
bs <- pmatch $ pmap # f # ks
|
||||||
|
pcon PTrue
|
||||||
|
|
||||||
|
f :: Term s (k :--> PMap k v :--> PMap k v)
|
||||||
|
f = plam $ \k m0' m1' -> P.do
|
||||||
|
PMap m0 <- m0'
|
||||||
|
PMap m1 <- m1'
|
||||||
|
pmatch (plookup # k # m1) $ \case
|
||||||
|
PNothing -> pconstant False
|
||||||
|
PJust n1 -> P.do
|
||||||
|
PJust n0 <- pmatch $ plookup # k # m0
|
||||||
|
n0 #<= n1
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- Functions which should (probably) not be upstreamed
|
-- Functions which should (probably) not be upstreamed
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue