agora/agora/Agora/Governor.hs
Seungheon Oh d2018afd4d Use liqwid-script-export
commit ec70bfd539fe2e27fd48f5f76395400287ac72d7
Author: Seungheon Oh <seungheon.ooh@gmail.com>
Date:   Tue Oct 18 18:58:59 2022 -0500

    use LSE

commit 25fff9b3ad1f2dde4cd7cf36977530b06a87d23c
Merge: 01cd3aa 1821dd6
Author: Seungheon Oh <seungheon.ooh@gmail.com>
Date:   Tue Oct 18 18:17:45 2022 -0500

    Merge branch 'staging' into seungheonoh/ply

commit 01cd3aa7a235e6fe6658246ca1026fa26dc71a83
Author: Hongrui Fang <chfanghr@gmail.com>
Date:   Tue Oct 11 12:02:03 2022 +0800

    update benchmark

commit a8513244892ce33cfdc9edf8cd501c4985ae8008
Author: Hongrui Fang <chfanghr@gmail.com>
Date:   Tue Oct 11 11:59:22 2022 +0800

    fix tests

commit 20ca40823485c2e2f78253643cf4453ac7b7ddd5
Author: Hongrui Fang <chfanghr@gmail.com>
Date:   Tue Oct 11 11:57:37 2022 +0800

    better import

commit a19fe49424210891bd03db71e4083fc1e0edfd98
Author: Hongrui Fang <chfanghr@gmail.com>
Date:   Tue Oct 11 11:08:20 2022 +0800

    update flake inputs

commit c93b21f1f9441e5c6f54525bf7c6a54757ec36cc
Author: Seungheon Oh <seungheon.ooh@gmail.com>
Date:   Mon Oct 10 12:54:12 2022 -0500

    tried to make tests pass

commit 1046ae1237299a33c58b48661bdb6d325a22147e
Merge: 2bf4e36 363bd83
Author: Seungheon Oh <seungheon.ooh@gmail.com>
Date:   Mon Oct 10 12:18:48 2022 -0500

    Merge branch 'staging' into seungheonoh/ply

commit 2bf4e3627c1b229f58078695082da85c80efd560
Author: Seungheon Oh <seungheon.ooh@gmail.com>
Date:   Mon Oct 10 10:48:36 2022 -0500

    remove junkpile

commit a1dbc9ad9e531fe0d0a0480c4aef9cf9ffa90f1d
Author: Seungheon Oh <seungheon.ooh@gmail.com>
Date:   Mon Oct 10 10:47:25 2022 -0500

    versions

commit 4542a06ac733858297d3a48c53368fad19dedc43
Author: Seungheon Oh <seungheon.ooh@gmail.com>
Date:   Thu Oct 6 22:57:48 2022 -0500

    script exporting interface

commit 6bd8c1a1d57e4bf9dc25c3068a9c8eae6bf6a19d
Author: Seungheon Oh <seungheon.ooh@gmail.com>
Date:   Thu Oct 6 22:58:41 2022 -0500

    fixed tests

commit d3ce2cf95633d336f3e621833677bd5bf10ee2c8
Author: Seungheon Oh <seungheon.ooh@gmail.com>
Date:   Sun Oct 2 00:55:18 2022 -0500

    fixed tests

commit 1ae64c9f692652b77b0506013853b2ba44267c65
Author: Seungheon Oh <seungheon.ooh@gmail.com>
Date:   Sat Oct 1 13:28:20 2022 -0500

    linker

commit db88cb75c7b74843141ad8ab4e6522b66d0dcfbc
Author: Seungheon Oh <seungheon.ooh@gmail.com>
Date:   Sat Oct 1 01:03:50 2022 -0500

    exporting scripts

commit 6389fce28e885a8a7f8669629c266f59c0edb51f
Author: Seungheon Oh <seungheon.ooh@gmail.com>
Date:   Sat Oct 1 00:51:49 2022 -0500

    made scripts parameterized on the script level

commit aea1e518a8890550bdebd0e5251da11d915c53a9
Author: Seungheon Oh <seungheon.ooh@gmail.com>
Date:   Wed Sep 28 19:53:29 2022 -0500

    Use `TypedScriptEnvelope` for `Agora.Bootstrap`
2022-10-18 19:02:10 -05:00

279 lines
7.3 KiB
Haskell

{-# LANGUAGE TemplateHaskell #-}
{- |
Module : Agora.Governor
Maintainer : connor@mlabs.city
Description: Governor entity scripts acting as authority of entire system.
Governor entity scripts acting as authority of entire system.
-}
module Agora.Governor (
-- * Haskell-land
GovernorDatum (..),
GovernorRedeemer (..),
Governor (..),
-- * Plutarch-land
PGovernorDatum (..),
PGovernorRedeemer (..),
-- * Utilities
pgetNextProposalId,
getNextProposalId,
pisGovernorDatumValid,
) where
import Agora.Aeson.Orphans ()
import Agora.Proposal (
PProposalId (PProposalId),
PProposalThresholds,
ProposalId (ProposalId),
ProposalThresholds,
pisProposalThresholdsValid,
)
import Agora.Proposal.Time (
MaxTimeRangeWidth,
PMaxTimeRangeWidth,
PProposalTimingConfig,
ProposalTimingConfig,
pisMaxTimeRangeWidthValid,
pisProposalTimingConfigValid,
)
import Agora.SafeMoney (GTTag)
import Data.Aeson qualified as Aeson
import Data.Tagged (Tagged)
import Plutarch.DataRepr (
DerivePConstantViaData (DerivePConstantViaData),
PDataFields,
)
import Plutarch.Extra.IsData (
DerivePConstantViaEnum (DerivePConstantEnum),
EnumIsData (EnumIsData),
PlutusTypeEnumData,
)
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pletFieldsC)
import Plutarch.Lift (PConstantDecl, PUnsafeLiftDecl (PLifted))
import PlutusLedgerApi.V1 (TxOutRef)
import PlutusLedgerApi.V1.Value (AssetClass)
import PlutusTx qualified
--------------------------------------------------------------------------------
{- | Datum for the Governor script.
@since 0.1.0
-}
data GovernorDatum = GovernorDatum
{ proposalThresholds :: ProposalThresholds
-- ^ Gets copied over upon creation of a 'Agora.Proposal.ProposalDatum'.
, nextProposalId :: ProposalId
-- ^ What tag the next proposal will get upon creating.
, proposalTimings :: ProposalTimingConfig
-- ^ The timing configuration for proposals.
-- Will get copied over upon the creation of proposals.
, createProposalTimeRangeMaxWidth :: MaxTimeRangeWidth
-- ^ The maximum valid duration of a transaction that creats a proposal.
, maximumProposalsPerStake :: Integer
-- ^ The maximum number of unfinished proposals that a stake is allowed to be
-- associated to.
}
deriving stock
( -- | @since 0.1.0
Show
, -- | @since 0.1.0
Generic
)
-- | @since 0.1.0
PlutusTx.makeIsDataIndexed ''GovernorDatum [('GovernorDatum, 0)]
{- | Redeemer for Governor script. The governor has two primary
responsibilities:
1. The gating of Proposal creation.
2. The gating of minting authority tokens.
Parameters of the governor can also be mutated by an effect.
@since 0.1.0
-}
data GovernorRedeemer
= -- | Checks that a proposal was created lawfully, and allows it.
CreateProposal
| -- | Checks that a SINGLE proposal finished correctly,
-- and allows minting GATs for each effect script.
MintGATs
| -- | Allows effects to mutate the parameters.
MutateGovernor
deriving stock
( -- | @since 0.1.0
Show
, -- | @since 0.1.0
Generic
, -- | @since 0.2.0
Enum
, -- | @since 0.2.0
Bounded
)
deriving
( -- | @since 0.1.0
PlutusTx.ToData
, -- | @since 0.1.0
PlutusTx.FromData
)
via (EnumIsData GovernorRedeemer)
{- | Parameters for creating Governor scripts.
@since 0.1.0
-}
data Governor = Governor
{ gstOutRef :: TxOutRef
-- ^ Referenced utxo will be spent to mint the GST.
, gtClassRef :: Tagged GTTag AssetClass
-- ^ Governance token of the system.
, maximumCosigners :: Integer
-- ^ Arbitrary limit for maximum amount of cosigners on a proposal.
-- See `Agora.Proposal.proposalDatumValid`.
}
deriving stock
( -- | @since 0.1.0
Generic
, -- | @since 0.2.0
Show
)
deriving anyclass
( -- | @since 1.0.0
Aeson.ToJSON
, -- | @since 1.0.0
Aeson.FromJSON
)
--------------------------------------------------------------------------------
{- | Plutarch-level datum for the Governor script.
@since 0.1.0
-}
newtype PGovernorDatum (s :: S) = PGovernorDatum
{ getGovernorDatum ::
Term
s
( PDataRecord
'[ "proposalThresholds" ':= PProposalThresholds
, "nextProposalId" ':= PProposalId
, "proposalTimings" ':= PProposalTimingConfig
, "createProposalTimeRangeMaxWidth" ':= PMaxTimeRangeWidth
, "maximumProposalsPerStake" ':= PInteger
]
)
}
deriving stock
( -- | @since 0.1.0
Generic
)
deriving anyclass
( -- | @since 0.1.0
PlutusType
, -- | @since 0.1.0
PIsData
, -- | @since 0.1.0
PDataFields
, -- | @since 0.1.0
PEq
)
-- | @since 0.2.0
instance DerivePlutusType PGovernorDatum where
type DPTStrat _ = PlutusTypeData
-- | @since 0.1.0
instance PUnsafeLiftDecl PGovernorDatum where type PLifted PGovernorDatum = GovernorDatum
-- | @since 0.1.0
deriving via (DerivePConstantViaData GovernorDatum PGovernorDatum) instance (PConstantDecl GovernorDatum)
-- | @since 0.1.0
deriving anyclass instance PTryFrom PData PGovernorDatum
{- | Plutarch-level version of 'GovernorRedeemer'.
@since 0.1.0
-}
data PGovernorRedeemer (s :: S)
= PCreateProposal
| PMintGATs
| PMutateGovernor
deriving stock
( -- | @since 0.1.0
Generic
, -- | @since 0.2.0
Enum
, -- | @since 0.2.0
Bounded
)
deriving anyclass
( -- | @since 0.1.0
PlutusType
, -- | @since 0.1.0
PIsData
, -- | @since 0.2.0
PEq
)
-- | @since 0.2.0
instance PTryFrom PData (PAsData PGovernorRedeemer)
-- | @since 0.2.0
instance DerivePlutusType PGovernorRedeemer where
type DPTStrat _ = PlutusTypeEnumData
-- | @since 0.1.0
instance PUnsafeLiftDecl PGovernorRedeemer where type PLifted PGovernorRedeemer = GovernorRedeemer
-- | @since 0.1.0
deriving via (DerivePConstantViaEnum GovernorRedeemer PGovernorRedeemer) instance (PConstantDecl GovernorRedeemer)
--------------------------------------------------------------------------------
{- | Plutrach version of 'getNextProposalId'.
@since 0.1.0
-}
pgetNextProposalId :: forall (s :: S). Term s (PProposalId :--> PProposalId)
pgetNextProposalId = phoistAcyclic $ plam $ \(pto -> pid) -> pcon $ PProposalId $ pid + 1
{- | Get next proposal id.
@since 0.1.0
-}
getNextProposalId :: ProposalId -> ProposalId
getNextProposalId (ProposalId pid) = ProposalId $ pid + 1
--------------------------------------------------------------------------------
{- | Check whether a particular 'PGovernorDatum' is well-formed.
@since 0.1.0
-}
pisGovernorDatumValid :: forall (s :: S). Term s (PGovernorDatum :--> PBool)
pisGovernorDatumValid = phoistAcyclic $
plam $ \datum -> unTermCont $ do
datumF <-
pletFieldsC
@'[ "proposalThresholds"
, "proposalTimings"
, "createProposalTimeRangeMaxWidth"
]
datum
pure $
foldr1
(#&&)
[ ptraceIfFalse "thresholds valid" $
pisProposalThresholdsValid # pfromData datumF.proposalThresholds
, ptraceIfFalse "timings valid" $
pisProposalTimingConfigValid # pfromData datumF.proposalTimings
, ptraceIfFalse "time range valid" $
pisMaxTimeRangeWidthValid # datumF.createProposalTimeRangeMaxWidth
]