diff --git a/agora/Agora/Effect/NoOp.hs b/agora/Agora/Effect/NoOp.hs index ccdae74..82069b9 100644 --- a/agora/Agora/Effect/NoOp.hs +++ b/agora/Agora/Effect/NoOp.hs @@ -14,6 +14,7 @@ import Plutarch.Api.V1 (PValidator) import Plutarch.TryFrom (PTryFrom (..)) import Plutus.V1.Ledger.Value (CurrencySymbol) +-- | Dummy datum for NoOp effect. newtype PNoOp (s :: S) = PNoOp (Term s PUnit) deriving (PlutusType, PIsData) via (DerivePNewtype PNoOp PUnit) diff --git a/agora/Agora/Effect/TreasuryWithdrawal.hs b/agora/Agora/Effect/TreasuryWithdrawal.hs index 8693cdf..e9957a4 100644 --- a/agora/Agora/Effect/TreasuryWithdrawal.hs +++ b/agora/Agora/Effect/TreasuryWithdrawal.hs @@ -40,7 +40,12 @@ import Plutus.V1.Ledger.Credential (Credential) import Plutus.V1.Ledger.Value (CurrencySymbol, Value) import PlutusTx qualified --- | Datum that encodes behavior of Treasury Withdrawal effect. +{- | Datum that encodes behavior of Treasury Withdrawal effect. + +Note: This Datum acts like a "predefined redeemer". Which is to say that +it encodes the properties a redeemer would, but is locked in-place until +spend. +-} data TreasuryWithdrawalDatum = TreasuryWithdrawalDatum { receivers :: [(Credential, Value)] -- ^ AssocMap for Value sent to each receiver from the treasury. @@ -51,8 +56,9 @@ data TreasuryWithdrawalDatum = TreasuryWithdrawalDatum deriving anyclass (Generic) PlutusTx.makeLift ''TreasuryWithdrawalDatum -PlutusTx.unstableMakeIsData ''TreasuryWithdrawalDatum +PlutusTx.makeIsDataIndexed ''TreasuryWithdrawalDatum [('TreasuryWithdrawalDatum, 0)] +-- | Haskell-level version of 'TreasuryWithdrawalDatum'. newtype PTreasuryWithdrawalDatum (s :: S) = PTreasuryWithdrawalDatum ( Term diff --git a/agora/Agora/Proposal.hs b/agora/Agora/Proposal.hs index bf88bf8..05a9f91 100644 --- a/agora/Agora/Proposal.hs +++ b/agora/Agora/Proposal.hs @@ -109,7 +109,7 @@ data ProposalStatus -- the proposal failed due to time constraints or didn't -- get to 'VotingReady' first. -- - -- At this stage, the 'votes' field of 'ProposalState' is frozen. + -- At this stage, the 'votes' field of 'ProposalDatum' is frozen. -- -- See 'AdvanceProposal' for documentation on state transitions. -- @@ -186,7 +186,7 @@ data ProposalRedeemer -- Must be signed by those cosigning. -- -- This is particularly used in the 'Draft' 'ProposalStatus', - -- where matching 'Stake's can be called to advance the proposal, + -- where matching 'Agora.Stake.Stake's can be called to advance the proposal, -- provided enough GT is shared among them. Cosign [PubKeyHash] | -- | Allow unlocking one or more stakes with votes towards particular 'ResultTag'. @@ -351,7 +351,7 @@ newtype PProposalDatum (s :: S) = PProposalDatum instance PUnsafeLiftDecl PProposalDatum where type PLifted PProposalDatum = ProposalDatum deriving via (DerivePConstantViaData ProposalDatum PProposalDatum) instance (PConstantDecl ProposalDatum) --- | Haskell-level redeemer for Proposal scripts. +-- | Plutarch-level version of 'ProposalRedeemer'. data PProposalRedeemer (s :: S) = PVote (Term s (PDataRecord '["resultTag" ':= PResultTag])) | PCosign (Term s (PDataRecord '["newCosigners" ':= PBuiltinList (PAsData PPubKeyHash)])) diff --git a/agora/Agora/Proposal/Time.hs b/agora/Agora/Proposal/Time.hs index 311c3fb..fd5063a 100644 --- a/agora/Agora/Proposal/Time.hs +++ b/agora/Agora/Proposal/Time.hs @@ -27,7 +27,15 @@ module Agora.Proposal.Time ( import Agora.Record (mkRecordConstr, (.&), (.=)) import GHC.Generics qualified as GHC import Generics.SOP (Generic, I (I)) -import Plutarch.Api.V1 (PExtended (PFinite), PInterval (PInterval), PLowerBound (PLowerBound), PMaybeData (PDJust, PDNothing), PPOSIXTime, PPOSIXTimeRange, PUpperBound (PUpperBound)) +import Plutarch.Api.V1 ( + PExtended (PFinite), + PInterval (PInterval), + PLowerBound (PLowerBound), + PMaybeData (PDJust, PDNothing), + PPOSIXTime, + PPOSIXTimeRange, + PUpperBound (PUpperBound), + ) import Plutarch.DataRepr (PDataFields, PIsDataReprInstances (..)) import Plutarch.Monadic qualified as P import Plutarch.Numeric (AdditiveSemigroup ((+))) @@ -74,16 +82,19 @@ newtype ProposalStartingTime = ProposalStartingTime deriving newtype (PlutusTx.ToData, PlutusTx.FromData, PlutusTx.UnsafeFromData) deriving stock (Eq, Show, GHC.Generic) --- | Configuration of proposal timings. +{- | Configuration of proposal timings. + + See: https://github.com/Liqwid-Labs/agora/blob/master/docs/tech-design/proposals.md#when-may-interactions-occur +-} data ProposalTimingConfig = ProposalTimingConfig { draftTime :: POSIXTime - -- ^ `D`: the length of the draft period. + -- ^ "D": the length of the draft period. , votingTime :: POSIXTime - -- ^ `V`: the length of the voting period. + -- ^ "V": the length of the voting period. , lockingTime :: POSIXTime - -- ^ `L`: the length of the locking period. + -- ^ "L": the length of the locking period. , executingTime :: POSIXTime - -- ^ `E`: the length of the execution period. + -- ^ "E": the length of the execution period. } deriving stock (Eq, Show, GHC.Generic) @@ -139,7 +150,7 @@ newtype PProposalTimingConfig (s :: S) = PProposalTimingConfig instance AdditiveSemigroup (Term s PPOSIXTime) where (punsafeCoerce @_ @_ @PInteger -> x) + (punsafeCoerce @_ @_ @PInteger -> y) = punsafeCoerce $ x + y --- | Get the current proposal time, from the 'txInfoValidRange' field. +-- | Get the current proposal time, from the 'Plutus.V1.Ledger.Api.txInfoValidRange' field. currentProposalTime :: forall (s :: S). Term s (PPOSIXTimeRange :--> PProposalTime) currentProposalTime = phoistAcyclic $ plam $ \iv -> P.do diff --git a/agora/Agora/Record.hs b/agora/Agora/Record.hs index 5ad5691..30d7490 100644 --- a/agora/Agora/Record.hs +++ b/agora/Agora/Record.hs @@ -60,7 +60,8 @@ mkRecordConstr :: forall (r :: [PLabeledType]) (s :: S) (pt :: PType). PlutusType pt => -- | The constructor. This is just the Haskell-level constructor for the type. - -- For 'PMaybeData', this could be 'PDJust', or 'PNothing'. + -- For 'Plutarch.Api.V1.Maybe.PMaybeData', this would + -- be 'Plutarch.Api.V1.Maybe.PDJust', or 'Plutarch.Api.V1.Maybe.PNothing'. (forall s'. Term s' (PDataRecord r) -> pt s') -> -- | The morphism that builds the record. RecordMorphism s '[] r -> @@ -87,7 +88,7 @@ infix 7 .= -- @#hello ~ 'FieldName' "hello"@ FieldName sym -> -- | The value at that field. This must be 'PAsData', because the underlying - -- type is @'Constr' 'Integer' ['Data']@. + -- type is @'PlutusCore.Data.Constr' 'Integer' ['PlutusCore.Data.Data']@. Term s (PAsData a) -> RecordMorphism s as ((sym ':= a) ': as) _ .= x = RecordMorphism $ pcon . PDCons x diff --git a/agora/Agora/Stake.hs b/agora/Agora/Stake.hs index efdc91b..6788f91 100644 --- a/agora/Agora/Stake.hs +++ b/agora/Agora/Stake.hs @@ -127,14 +127,14 @@ data StakeRedeemer | -- | Destroy a stake, retrieving its LQ, the minimum ADA and any other assets. -- Stake must be unlocked. Destroy - | -- | Permit a Vote to be added onto a 'Proposal'. + | -- | Permit a Vote to be added onto a 'Agora.Proposal.Proposal'. -- This also adds a lock to the 'lockedBy' field. See 'ProposalLock'. -- This needs to be done in sync with casting a vote, otherwise -- it's possible for a lock to be permanently placed on the stake, -- and then the funds are lost. PermitVote ProposalLock | -- | Retract a vote, removing it from the 'lockedBy' field. See 'ProposalLock'. - -- This action checks for permission of the 'Proposal'. Finished proposals are + -- This action checks for permission of the 'Agora.Proposal.Proposal'. Finished proposals are -- always allowed to have votes retracted and won't affect the Proposal datum, -- allowing 'Stake's to be unlocked. RetractVotes [ProposalLock] @@ -156,7 +156,7 @@ PlutusTx.makeIsDataIndexed data StakeDatum = StakeDatum { stakedAmount :: Tagged GTTag Integer -- ^ Tracks the amount of governance token staked in the datum. - -- This also acts as the voting weight for 'Proposal's. + -- This also acts as the voting weight for 'Agora.Proposal.Proposal's. , owner :: PubKeyHash -- ^ The hash of the public key this stake belongs to. -- @@ -218,6 +218,7 @@ deriving via instance PUnsafeLiftDecl PStakeRedeemer where type PLifted PStakeRedeemer = StakeRedeemer deriving via (DerivePConstantViaData StakeRedeemer PStakeRedeemer) instance (PConstantDecl StakeRedeemer) +-- | Plutarch-level version of 'ProposalLock'. newtype PProposalLock (s :: S) = PProposalLock { getProposalLock :: Term diff --git a/agora/Agora/Stake/Scripts.hs b/agora/Agora/Stake/Scripts.hs index f07ace3..44cefac 100644 --- a/agora/Agora/Stake/Scripts.hs +++ b/agora/Agora/Stake/Scripts.hs @@ -54,15 +54,16 @@ import Prelude hiding (Num (..)) === For minting: - - Check that exactly one state thread is minted - - Check that an output exists with a state thread and a valid datum - - Check that no state thread is an input - - assert @'TokenName' == 'ValidatorHash'@ of the script that we pay to + - Check that exactly one state thread is minted. + - Check that an output exists with a state thread and a valid datum. + - Check that no state thread is an input. + - assert @'Plutus.V1.Ledger.Api.TokenName' == 'Plutus.V1.Ledger.Api.ValidatorHash'@ + of the script that we pay to. === For burning: - - Check that exactly one state thread is burned - - Check that datum at state thread is valid and not locked + - Check that exactly one state thread is burned. + - Check that datum at state thread is valid and not locked. -} stakePolicy :: Tagged GTTag AssetClass -> ClosedTerm PMintingPolicy stakePolicy gtClassRef = diff --git a/agora/Agora/Treasury.hs b/agora/Agora/Treasury.hs index db9172f..f3ff441 100644 --- a/agora/Agora/Treasury.hs +++ b/agora/Agora/Treasury.hs @@ -29,8 +29,10 @@ import PlutusTx qualified -------------------------------------------------------------------------------- +-- | Redeemer for Treasury actions. data TreasuryRedeemer - = SpendTreasuryGAT + = -- | Allow transaction to pass by delegating to GAT burn. + SpendTreasuryGAT deriving stock (Eq, Show, GHC.Generic) PlutusTx.makeIsDataIndexed