diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index a322382..b099c4d 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -6,6 +6,6 @@ - [ ] I have ensured documentation and testing are thorough. - [ ] I have updated the changelog. -- [ ] I have read [CONTRIBUTING.md][../CONTRIBUTING.md] +- [ ] I have read [CONTRIBUTING.md](../CONTRIBUTING.md) - [ ] I have made sure the CI checks run using `nix run .#ci`. - [ ] I have followed the code standards to the best of my ability or have documented carefully where and why I haven't. diff --git a/CHANGELOG.md b/CHANGELOG.md index 70dbaee..a04a673 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,35 @@ This format is based on [Keep A Changelog](https://keepachangelog.com/en/1.0.0). ### Modified +- Mitigate potential DDoS attack(voting and unlocking repeatedly) + + We fix this issue by posing cooldown time while retracting votes, encoded in + `ProposalTimingConfig`'s `minStakeVotingTime` field. Also to make sure that + stake owners can unlock their stakes in s reasonable time, we pose a maximum + time range width requirement while voting, encoded in `ProposalTimingConfig`'s `votingTimeRangeMaxWidth` field. + + Included by [#209](https://github.com/Liqwid-Labs/agora/pull/209) + +- Fix several vulnerabilities and bugs found by auditors. + + Including: + - A bug that allows multiple GATs to be minted into a single UTxO and sent + to a malicious script. + - A bug that allows delegates to create or cosign proposals with delegated + stakes. + - Potential DDoS attack: calling `UnlockStake` without any stake. + - Potential DDoS attack: calling `UnlockStake` on a `VotingReady` proposal + without actually changing the votes. + - Ignore staking credential in proposal, stake and governor. + - Improve naming and doc strings to avoid confusion. + + Included by [#208](https://github.com/Liqwid-Labs/agora/pull/208) + +- Allow delegates to vote and retract vote with their stakes along side with + stakes delegated to them in the same transaction. + + Included by [#208](https://github.com/Liqwid-Labs/agora/pull/208) + - Fix several vulnerabilities and bugs found in both proposal and governor scripts. Including: @@ -150,7 +179,7 @@ the stake validator easily. The behaviour of the default stake validator remains Included by [#146](https://github.com/Liqwid-Labs/agora/pull/146). -- Draft phase and cosigning for Proposals. +- Draft phase and cosigning for Proposals. Included by [#136](https://github.com/Liqwid-Labs/agora/pull/136). @@ -158,7 +187,7 @@ the stake validator easily. The behaviour of the default stake validator remains Included by [#134](https://github.com/Liqwid-Labs/agora/pull/134). -- Fixed bug that made it impossible to create proposals. Added new stake locking mechanism for creating proposals. +- Fixed bug that made it impossible to create proposals. Added new stake locking mechanism for creating proposals. Included by [#142](https://github.com/Liqwid-Labs/agora/pull/142). diff --git a/agora-scripts/Main.hs b/agora-scripts/Main.hs index c56740b..e1aa7f5 100644 --- a/agora-scripts/Main.hs +++ b/agora-scripts/Main.hs @@ -9,10 +9,13 @@ module Main (main) where import Agora.Bootstrap qualified as Bootstrap -import Agora.Linker +import Agora.Linker (linker) import Data.Default (def) -import ScriptExport.Export -import ScriptExport.Types +import ScriptExport.Export (exportMain) +import ScriptExport.Types ( + Builders, + insertScriptExportWithLinker, + ) main :: IO () main = exportMain builders diff --git a/agora-specs/Property/Governor.hs b/agora-specs/Property/Governor.hs index 176773f..cbd9a08 100644 --- a/agora-specs/Property/Governor.hs +++ b/agora-specs/Property/Governor.hs @@ -1,3 +1,7 @@ +{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} + +{-# HLINT ignore "Redundant bracket" #-} + {- | Module : Property.Governor Maintainer : seungheon.ooh@gmail.com @@ -7,19 +11,35 @@ Property model and tests for 'Governor' related functions -} module Property.Governor (props) where -import Agora.Governor (Governor (gstOutRef), GovernorDatum (..), pisGovernorDatumValid) +import Agora.Governor ( + GovernorDatum ( + GovernorDatum, + createProposalTimeRangeMaxWidth, + maximumCreatedProposalsPerStake, + nextProposalId, + proposalThresholds, + proposalTimings + ), + PGovernorDatum, + pisGovernorDatumValid, + ) import Agora.Governor.Scripts (governorPolicy) import Agora.Proposal ( ProposalId (ProposalId), - ProposalThresholds (ProposalThresholds), + ProposalThresholds ( + ProposalThresholds + ), ) import Agora.Proposal.Time ( MaxTimeRangeWidth (MaxTimeRangeWidth), ProposalTimingConfig (ProposalTimingConfig), ) -import Data.Default.Class (Default (def)) +import Data.Default (def) import Data.Tagged (Tagged (Tagged)) -import Data.Universe (Finite (..), Universe (..)) +import Data.Universe (Universe) +import Data.Universe.Class (Finite) +import Generics.SOP.NP (NP (Nil, (:*))) +import Optics (view) import Plutarch.Api.V2 (PScriptContext) import Plutarch.Builtin (pforgetData) import Plutarch.Context ( @@ -34,31 +54,42 @@ import Plutarch.Context ( withRef, withValue, ) +import Plutarch.Evaluate (evalTerm) import Plutarch.Extra.AssetClass (assetClassValue) -import PlutusLedgerApi.V2 ( - ScriptContext (scriptContextTxInfo), - TxInInfo (txInInfoOutRef), - TxInfo (txInfoInputs, txInfoMint, txInfoOutputs), - TxOut (txOutValue), +import Plutarch.Extra.Compile (mustCompile) +import Plutarch.Test.QuickCheck ( + Equality (OnPEq), + Partiality (ByComplete), + TestableTerm (TestableTerm), + haskEquiv, + pconstantT, + shouldCrash, + shouldRun, ) +import PlutusLedgerApi.V2 (Script, ScriptContext) import Property.Generator (genInput, genOutput) import Sample.Shared ( + deterministicTracingConfig, governor, governorAssetClass, governorSymbol, governorValidatorHash, gstUTXORef, ) -import Test.Tasty (TestTree) -import Test.Tasty.Plutarch.Property (classifiedPropertyNative) -import Test.Tasty.QuickCheck ( +import Test.QuickCheck ( + Arbitrary (arbitrary), Gen, Property, + arbitraryBoundedEnum, + checkCoverage, choose, chooseInteger, + cover, + forAll, listOf1, - testProperty, ) +import Test.Tasty (TestTree, adjustOption, testGroup) +import Test.Tasty.QuickCheck (QuickCheckTests, testProperty) data GovernorDatumCases = ExecuteLE0 @@ -67,172 +98,211 @@ data GovernorDatumCases | VoteLE0 | CosignLE0 | Correct - deriving stock (Eq, Show) + deriving stock (Eq, Show, Enum, Bounded) + deriving anyclass (Universe, Finite) -instance Universe GovernorDatumCases where - universe = - [ ExecuteLE0 - , CreateLE0 - , VoteLE0 - , CosignLE0 - , Correct - ] +instance Arbitrary GovernorDatumCases where + arbitrary = arbitraryBoundedEnum -instance Finite GovernorDatumCases where - universeF = universe - cardinality = Tagged 6 - -{- | Property that checks `governorDatumValid`. - `governorDatumValid` determines if given governor datum is valid or not. This property - ensures `governorDatumValid` is checking the datum correctly and ruling out improper datum. +{- | Property that checks `pisGovernorDatumValid` behaves as intended by + comparing it to a simple haskell implementation. -} governorDatumValidProperty :: Property governorDatumValidProperty = - classifiedPropertyNative gen (const []) expected classifier pisGovernorDatumValid + haskEquiv @( 'OnPEq) @( 'ByComplete) + isValidModelImpl + (TestableTerm pisGovernorDatumValid) + (genDatum :* Nil) where - classifier :: GovernorDatum -> GovernorDatumCases - classifier - ( (.proposalThresholds) -> - ProposalThresholds - execute - create - toVoting - vote - cosign - ) - | execute < 0 = ExecuteLE0 - | create < 0 = CreateLE0 - | toVoting < 0 = ToVotingLE0 - | vote < 0 = VoteLE0 - | cosign < 0 = CosignLE0 - | otherwise = Correct - - expected :: GovernorDatum -> Maybe Bool - expected c = Just $ classifier c == Correct - - gen :: GovernorDatumCases -> Gen GovernorDatum - gen c = do - thres <- genProposalThresholds c - - let timing = ProposalTimingConfig 0 0 0 0 - return $ GovernorDatum thres (ProposalId 0) timing (MaxTimeRangeWidth 1) 3 + genDatum :: Gen (TestableTerm PGovernorDatum) + genDatum = pconstantT <$> (arbitrary >>= genDatumForCase) where - taggedInteger p = Tagged <$> chooseInteger p - genProposalThresholds :: GovernorDatumCases -> Gen ProposalThresholds - genProposalThresholds c = do - let validGT = taggedInteger (0, 1000000000) - execute <- validGT - create <- validGT - toVoting <- validGT - vote <- validGT - cosign <- validGT - le0 <- taggedInteger (-1000, -1) + genDatumForCase :: GovernorDatumCases -> Gen GovernorDatum + genDatumForCase c = do + thres <- genProposalThresholds c - case c of - ExecuteLE0 -> - -- execute < 0 - return $ ProposalThresholds le0 create toVoting vote cosign - CreateLE0 -> - -- c < 0 - return $ ProposalThresholds execute le0 toVoting vote cosign - ToVotingLE0 -> - return $ ProposalThresholds execute create le0 vote cosign - VoteLE0 -> - -- vote < 0 - return $ ProposalThresholds execute create toVoting le0 cosign - CosignLE0 -> - return $ ProposalThresholds execute create toVoting vote le0 - Correct -> - return $ ProposalThresholds execute create toVoting vote cosign + let timing = ProposalTimingConfig 0 0 0 0 0 0 + pure $ + GovernorDatum thres (ProposalId 0) timing (MaxTimeRangeWidth 1) 3 + where + taggedInteger p = Tagged <$> chooseInteger p + genProposalThresholds :: GovernorDatumCases -> Gen ProposalThresholds + genProposalThresholds c = do + let validGT = taggedInteger (0, 1000000000) + execute <- validGT + create <- validGT + toVoting <- validGT + vote <- validGT + cosign <- validGT + le0 <- taggedInteger (-1000, -1) + + case c of + ExecuteLE0 -> + -- execute < 0 + return $ ProposalThresholds le0 create toVoting vote cosign + CreateLE0 -> + -- c < 0 + return $ ProposalThresholds execute le0 toVoting vote cosign + ToVotingLE0 -> + return $ ProposalThresholds execute create le0 vote cosign + VoteLE0 -> + -- vote < 0 + return $ ProposalThresholds execute create toVoting le0 cosign + CosignLE0 -> + return $ ProposalThresholds execute create toVoting vote le0 + Correct -> + return $ ProposalThresholds execute create toVoting vote cosign + + -- \| This is a model Haskell implementation of `pisGovernorDatumValid`. + isValidModelImpl :: GovernorDatum -> Bool + isValidModelImpl = correctCase . classifier + where + correctCase = \case + Correct -> True + _ -> False + + classifier :: GovernorDatum -> GovernorDatumCases + classifier + ( view #proposalThresholds -> + ProposalThresholds + execute + create + toVoting + vote + cosign + ) + | execute < 0 = ExecuteLE0 + | create < 0 = CreateLE0 + | toVoting < 0 = ToVotingLE0 + | vote < 0 = VoteLE0 + | cosign < 0 = CosignLE0 + | otherwise = Correct + +-------------------------------------------------------------------------------- data GovernorPolicyCases = ReferenceUTXONotSpent | IncorrectAmountOfTokenMinted | GovernorOutputNotFound - | GovernorPolicyCorrect deriving stock (Eq, Show) -instance Universe GovernorPolicyCases where - universe = - [ ReferenceUTXONotSpent - , IncorrectAmountOfTokenMinted - , GovernorOutputNotFound - , GovernorPolicyCorrect - ] +governorMintingPolicyTests :: [TestTree] +governorMintingPolicyTests = + [ mkGovMintingCasePropertyTest + "Reference input spend test" + ReferenceUTXONotSpent + "Spent" + "Not spent" + , mkGovMintingCasePropertyTest + "Amount of token minted test" + IncorrectAmountOfTokenMinted + "Correct" + "Incorrect" + , mkGovMintingCasePropertyTest + "Governor output presense" + GovernorOutputNotFound + "Present" + "Absent" + ] -instance Finite GovernorPolicyCases where - universeF = universe - cardinality = Tagged 4 +{- | Creates a property by compiling governorPolicy script with given arguments + and checking if it runs as expected by a test. +-} +governorPolicyValid :: ScriptContext -> Bool -> Property +governorPolicyValid ctx shouldSucceed = + let mp = mkPolicyScript ctx in if shouldSucceed then shouldRun mp else shouldCrash mp -governorMintingProperty :: Property -governorMintingProperty = - classifiedPropertyNative gen (const []) expected classifier actual +{-# INLINEABLE mkPolicyScript #-} +mkPolicyScript :: ScriptContext -> Script +mkPolicyScript ctx = mustCompile (go # pconstant ctx) where - {- Note: - I don't think it's easily possible to randomize orefs. We can't really pass pass `Governor` type to `actual` function. - -} - gst = assetClassValue governorAssetClass 1 - mintAmount x = mint . mconcat $ replicate x gst - outputToGov = - output $ - mconcat - [ script governorValidatorHash - , withValue gst - , withDatum govDatum - ] - referencedInput = input $ withRef gstUTXORef + go :: forall (s :: S). Term s (PScriptContext :--> POpaque) + go = loudEval $ + plam $ \sc -> + governorPolicy + # pconstant (view #gstOutRef governor) + # pforgetData (pconstantData ()) + # sc - govDatum :: GovernorDatum - govDatum = - GovernorDatum - { proposalThresholds = def - , nextProposalId = ProposalId 0 - , proposalTimings = def - , createProposalTimeRangeMaxWidth = def - , maximumProposalsPerStake = 3 - } - - gen :: GovernorPolicyCases -> Gen ScriptContext +-- | Prepares a minting policy test for given policy error case. +mkGovMintingCasePropertyTest :: + String -> + GovernorPolicyCases -> + String -> + String -> + TestTree +mkGovMintingCasePropertyTest name case' positiveCaseName negativeCaseName = + testProperty name $ + forAll (gen case') $ + \(ctx, valid) -> + checkCoverage $ + cover 48 valid positiveCaseName $ + cover 48 (not valid) negativeCaseName $ + governorPolicyValid ctx valid + where + gen :: GovernorPolicyCases -> Gen (ScriptContext, Bool) gen c = do inputs <- fmap mconcat . listOf1 $ genInput @MintingBuilder outputs <- fmap mconcat . listOf1 $ genOutput @MintingBuilder toks <- choose (2, 100) + valid <- arbitrary let comp = - case c of - ReferenceUTXONotSpent -> outputToGov <> mintAmount 1 - IncorrectAmountOfTokenMinted -> referencedInput <> outputToGov <> mintAmount toks - GovernorOutputNotFound -> referencedInput <> mintAmount 1 - GovernorPolicyCorrect -> referencedInput <> outputToGov <> mintAmount 1 + if valid + then referencedInput <> outputToGov <> mintAmount 1 + else case c of + ReferenceUTXONotSpent -> outputToGov <> mintAmount 1 + IncorrectAmountOfTokenMinted -> + referencedInput + <> outputToGov + <> mintAmount toks + GovernorOutputNotFound -> referencedInput <> mintAmount 1 - return . buildMinting' $ inputs <> outputs <> comp <> withMinting governorSymbol - - expected :: ScriptContext -> Maybe () - expected sc = - case classifier sc of - GovernorPolicyCorrect -> Just () - _ -> Nothing - - opaqueToUnit :: Term s (POpaque :--> PUnit) - opaqueToUnit = plam $ \_ -> pconstant () - - actual :: Term s (PScriptContext :--> PUnit) - actual = plam $ \sc -> opaqueToUnit #$ governorPolicy # pconstant governor.gstOutRef # pforgetData (pconstantData ()) # sc - - classifier :: ScriptContext -> GovernorPolicyCases - classifier sc - | minted /= gst = IncorrectAmountOfTokenMinted - | refInputNotExists = ReferenceUTXONotSpent - | govOutputNotExists = GovernorOutputNotFound - | otherwise = GovernorPolicyCorrect + let ctx = + buildMinting' $ + inputs + <> outputs + <> comp + <> withMinting + governorSymbol + pure (ctx, valid) where - txinfo = scriptContextTxInfo sc - minted = txInfoMint txinfo - refInputNotExists = gstUTXORef `notElem` (txInInfoOutRef <$> txInfoInputs txinfo) - govOutputNotExists = gst `notElem` (txOutValue <$> txInfoOutputs txinfo) + govDatum :: GovernorDatum + govDatum = + GovernorDatum + { proposalThresholds = def + , nextProposalId = ProposalId 0 + , proposalTimings = def + , createProposalTimeRangeMaxWidth = def + , maximumCreatedProposalsPerStake = 3 + } + + gst = assetClassValue governorAssetClass 1 + mintAmount x = mint . mconcat $ replicate x gst + referencedInput = input $ withRef gstUTXORef + outputToGov = + output $ + mconcat + [ script governorValidatorHash + , withValue gst + , withDatum govDatum + ] props :: [TestTree] props = - [ testProperty "governorDatumValid" governorDatumValidProperty - , testProperty "governorPolicy" governorMintingProperty + [ adjustOption go . testProperty "governorDatumValid" $ governorDatumValidProperty + , testGroup "governorPolicy" governorMintingPolicyTests ] + where + go :: QuickCheckTests -> QuickCheckTests + go = max 20_000 + +loudEval :: + forall (p :: S -> Type). + ClosedTerm p -> + ClosedTerm p +loudEval x = + case evalTerm deterministicTracingConfig x of + Right (Right t, _, _) -> t + Right (Left err, _, trace) -> error $ show err <> show trace + Left err -> error $ show err diff --git a/agora-specs/Sample/AuthorityToken/UnauthorizedMintingExploit.hs b/agora-specs/Sample/AuthorityToken/UnauthorizedMintingExploit.hs new file mode 100644 index 0000000..27791bc --- /dev/null +++ b/agora-specs/Sample/AuthorityToken/UnauthorizedMintingExploit.hs @@ -0,0 +1,66 @@ +module Sample.AuthorityToken.UnauthorizedMintingExploit ( + Parameters (..), + exploit, + mkTestCase, +) where + +import Control.Exception (assert) +import Plutarch.Context (input, mint, normalizeValue, output, script, withValue) +import Plutarch.Extra.ScriptContext (validatorHashToTokenName) +import PlutusLedgerApi.V1.Value qualified as Value +import Sample.Shared (authorityTokenPolicy, authorityTokenSymbol, minAda) +import Test.Specification (SpecificationTree, testPolicy) +import Test.Util (CombinableBuilder, mkMinting, validatorHashes) + +data Parameters = Parameters + { burntGAT :: Int + , mintedGAT :: Int + } + +exploit :: + forall b. + CombinableBuilder b => + Parameters -> + b +exploit (Parameters burntGAT mintedGAT) = + assert (burntGAT > mintedGAT && mintedGAT > 0) $ + effectInputBuilder <> maliciousGATOutputBuilder + where + (effectScriptHashes, rest) = splitAt burntGAT validatorHashes + maliciousScripts = take mintedGAT rest + + gatValue hash = + Value.singleton + authorityTokenSymbol + (validatorHashToTokenName hash) + + mkGATUTxO hash = + mconcat + [ script hash + , withValue $ normalizeValue $ minAda <> gatValue hash 1 + ] + + effectInputBuilder = + foldMap + ( \effectHash -> + mconcat + [ mint $ gatValue effectHash $ negate 1 + , input $ mkGATUTxO effectHash + ] + ) + effectScriptHashes + + maliciousGATOutputBuilder = + foldMap + ( \scriptHash -> + mconcat + [ mint $ gatValue scriptHash 1 + , output $ mkGATUTxO scriptHash + ] + ) + maliciousScripts + +mkTestCase :: String -> Parameters -> SpecificationTree +mkTestCase name ps = + testPolicy False name authorityTokenPolicy () $ + mkMinting exploit ps authorityTokenSymbol diff --git a/agora-specs/Sample/Effect/GovernorMutation.hs b/agora-specs/Sample/Effect/GovernorMutation.hs index 21a88b6..dd25bed 100644 --- a/agora-specs/Sample/Effect/GovernorMutation.hs +++ b/agora-specs/Sample/Effect/GovernorMutation.hs @@ -17,12 +17,12 @@ import Agora.Effect.GovernorMutation ( import Agora.Governor (GovernorDatum (..), GovernorRedeemer (MutateGovernor)) import Agora.Proposal (ProposalId (..), ProposalThresholds (..)) import Agora.SafeMoney (AuthorityTokenTag) -import Agora.Utils (validatorHashToTokenName) import Data.Default.Class (Default (def)) import Data.Map ((!)) import Data.Tagged (Tagged (..)) import Plutarch.Api.V2 (validatorHash) import Plutarch.Extra.AssetClass (AssetClass (AssetClass), assetClassValue) +import Plutarch.Extra.ScriptContext (validatorHashToTokenName) import PlutusLedgerApi.V1 qualified as Interval (always) import PlutusLedgerApi.V1.Address (scriptHashAddress) import PlutusLedgerApi.V1.Value qualified as Value ( @@ -114,7 +114,7 @@ mkEffectTxInfo newGovDatum = , nextProposalId = ProposalId 0 , proposalTimings = def , createProposalTimeRangeMaxWidth = def - , maximumProposalsPerStake = 3 + , maximumCreatedProposalsPerStake = 3 } governorInputDatum :: Datum governorInputDatum = Datum $ toBuiltinData governorInputDatum' @@ -186,7 +186,7 @@ validNewGovernorDatum = , nextProposalId = ProposalId 42 , proposalTimings = def , createProposalTimeRangeMaxWidth = def - , maximumProposalsPerStake = 3 + , maximumCreatedProposalsPerStake = 3 } invalidNewGovernorDatum :: GovernorDatum @@ -199,5 +199,5 @@ invalidNewGovernorDatum = , nextProposalId = ProposalId 42 , proposalTimings = def , createProposalTimeRangeMaxWidth = def - , maximumProposalsPerStake = 3 + , maximumCreatedProposalsPerStake = 3 } diff --git a/agora-specs/Sample/Governor/Initialize.hs b/agora-specs/Sample/Governor/Initialize.hs index e365f9b..e080923 100644 --- a/agora-specs/Sample/Governor/Initialize.hs +++ b/agora-specs/Sample/Governor/Initialize.hs @@ -58,7 +58,7 @@ import PlutusLedgerApi.V2 ( ValidatorHash, ) import Sample.Shared ( - deterministicTracingConfing, + deterministicTracingConfig, minAda, ) import Sample.Shared qualified as Shared @@ -72,7 +72,7 @@ data Parameters = Parameters -- ^ Whether the 'GovernorDatum.proposalThresholds' field of the output -- governor datum is valid or not. , datumMaxTimeRangeWidthValid :: Bool - -- ^ Whether the 'GovernorDatum.maximumProposalsPerStake'field of the + -- ^ Whether the 'GovernorDatum.maximumCreatedProposalsPerStake'field of the -- output governor datum is valid or not. , datumTimingConfigValid :: Bool -- ^ Whether the 'GovernorDatum.proposalTimings'field of the output @@ -96,7 +96,7 @@ validGovernorOutputDatum = , nextProposalId = ProposalId 0 , proposalTimings = def , createProposalTimeRangeMaxWidth = def - , maximumProposalsPerStake = 3 + , maximumCreatedProposalsPerStake = 3 } invalidProposalThresholds :: ProposalThresholds @@ -106,7 +106,7 @@ invalidMaxTimeRangeWidth :: MaxTimeRangeWidth invalidMaxTimeRangeWidth = MaxTimeRangeWidth 0 invalidProposalTimings :: ProposalTimingConfig -invalidProposalTimings = ProposalTimingConfig (-1) (-1) (-1) (-1) +invalidProposalTimings = ProposalTimingConfig (-1) (-1) (-1) (-1) (-1) (-1) witnessRef :: TxOutRef witnessRef = TxOutRef "b0353c22b0bd6c5296a8eef160ba25d90b5dc82a9bb8bdaa6823ffc19515d6ad" 0 @@ -124,7 +124,7 @@ scripts = (fmap (view #script) . view #scripts) ( runLinker linker - (agoraScripts deterministicTracingConfing) + (agoraScripts deterministicTracingConfig) governor ) diff --git a/agora-specs/Sample/Governor/Mutate.hs b/agora-specs/Sample/Governor/Mutate.hs index 029a030..11577f7 100644 --- a/agora-specs/Sample/Governor/Mutate.hs +++ b/agora-specs/Sample/Governor/Mutate.hs @@ -18,7 +18,6 @@ module Sample.Governor.Mutate ( import Agora.Governor (GovernorDatum (..), GovernorRedeemer (MutateGovernor)) import Agora.Proposal (ProposalId (ProposalId), ProposalThresholds (..)) -import Agora.Utils (scriptHashToTokenName) import Data.Default (def) import Data.Map ((!)) import Plutarch.Api.V2 (PMintingPolicy, mintingPolicySymbol, mkMintingPolicy, validatorHash) @@ -33,6 +32,7 @@ import Plutarch.Context ( withValue, ) import Plutarch.Extra.AssetClass (assetClassValue) +import Plutarch.Extra.ScriptContext (scriptHashToTokenName) import PlutusLedgerApi.V1.Value qualified as Value import PlutusLedgerApi.V2 ( CurrencySymbol (CurrencySymbol), @@ -105,7 +105,7 @@ governorInputDatum = , nextProposalId = ProposalId 0 , proposalTimings = def , createProposalTimeRangeMaxWidth = def - , maximumProposalsPerStake = 3 + , maximumCreatedProposalsPerStake = 3 } mkGovernorOutputDatum :: @@ -115,7 +115,7 @@ mkGovernorOutputDatum DatumValid = Just $ toData $ governorInputDatum - { maximumProposalsPerStake = 4 + { maximumCreatedProposalsPerStake = 4 } mkGovernorOutputDatum ValueInvalid = let invalidProposalThresholds = diff --git a/agora-specs/Sample/Proposal/Advance.hs b/agora-specs/Sample/Proposal/Advance.hs index 32bf0f9..c36a878 100644 --- a/agora-specs/Sample/Proposal/Advance.hs +++ b/agora-specs/Sample/Proposal/Advance.hs @@ -35,12 +35,14 @@ module Sample.Proposal.Advance ( mkMintGATsWithoutTagBundle, mkBadGovernorOutputDatumBundle, mkUnexpectedOutputStakeBundles, + mkFastforwardToFinishBundles, + mkBadGovernorRedeemerBundle, ) where import Agora.Governor ( Governor (..), GovernorDatum (..), - GovernorRedeemer (MintGATs), + GovernorRedeemer (CreateProposal, MintGATs), ) import Agora.Proposal ( ProposalDatum (..), @@ -67,7 +69,6 @@ import Agora.SafeMoney (AuthorityTokenTag, GTTag) import Agora.Stake ( StakeDatum (..), ) -import Agora.Utils (scriptHashToTokenName) import Control.Applicative (liftA2) import Control.Monad.State (execState, modify, when) import Data.Default (def) @@ -85,10 +86,12 @@ import Plutarch.Context ( timeRange, withDatum, withInlineDatum, + withRedeemer, withRef, withValue, ) import Plutarch.Extra.AssetClass (AssetClass (AssetClass), assetClassValue) +import Plutarch.Extra.ScriptContext (scriptHashToTokenName) import Plutarch.Lift (PLifted, PUnsafeLiftDecl) import PlutusLedgerApi.V2 ( Credential (PubKeyCredential), @@ -100,6 +103,7 @@ import PlutusLedgerApi.V2 ( TxOutRef (TxOutRef), ValidatorHash, ) +import PlutusTx qualified import Sample.Proposal.Shared ( governorTxRef, proposalTxRef, @@ -164,9 +168,18 @@ data ParameterBundle = ParameterBundle } -- | Everything about the generated governor stuff. -newtype GovernorParameters = GovernorParameters +data GovernorParameters = forall + (redeemer :: Type) + (predeemer :: PType). + ( PUnsafeLiftDecl predeemer + , PLifted predeemer ~ redeemer + , PIsData predeemer + , PlutusTx.ToData redeemer + ) => + GovernorParameters { invalidGovernorOutputDatum :: Bool -- ^ The output governor datum will be changed. + , governorRedeemer :: redeemer } -- | Everything about the generated authority token stuff. @@ -278,7 +291,7 @@ mkVotes ps = -- | The starting time of every generated proposal. proposalStartingTime :: POSIXTime -proposalStartingTime = 0 +proposalStartingTime = 100 -- | Create the input proposal datum given the parameters. mkProposalInputDatum :: ProposalParameters -> ProposalDatum @@ -413,14 +426,14 @@ governorInputDatum = , nextProposalId = ProposalId 42 , proposalTimings = def , createProposalTimeRangeMaxWidth = def - , maximumProposalsPerStake = 3 + , maximumCreatedProposalsPerStake = 3 } -- | Create the output governor datum given the parameters. mkGovernorOutputDatum :: GovernorParameters -> GovernorDatum mkGovernorOutputDatum ps = if ps.invalidGovernorOutputDatum - then governorInputDatum {maximumProposalsPerStake = 15} + then governorInputDatum {maximumCreatedProposalsPerStake = 15} else governorInputDatum -- | Reference to the governor UTXO. @@ -431,7 +444,7 @@ governorRef = TxOutRef governorTxRef 2 governor validator. -} mkGovernorBuilder :: forall b. CombinableBuilder b => GovernorParameters -> b -mkGovernorBuilder ps = +mkGovernorBuilder ps@(GovernorParameters _ redeemer) = let gst = assetClassValue governorAssetClass 1 value = sortValue $ gst <> minAda in mconcat @@ -441,6 +454,7 @@ mkGovernorBuilder ps = , withValue value , withRef governorRef , withDatum governorInputDatum + , withRedeemer redeemer ] , output $ mconcat @@ -451,12 +465,6 @@ mkGovernorBuilder ps = ] ] -{- | The proposal redeemer used to spend the governor UTXO, which is always - 'MintGATs' in this case. --} -governorRedeemer :: GovernorRedeemer -governorRedeemer = MintGATs - -------------------------------------------------------------------------------- -- * Authority Token @@ -537,16 +545,22 @@ mkTestTree name pb val = proposalInputDatum proposalRedeemer (spend proposalRef) + governor = - maybe [] singleton $ - testValidator - (fromJust val.forGovernorValidator) - "governor" - governorValidator - governorInputDatum - governorRedeemer - (spend governorRef) - <$ pb.governorParameters + maybe + [] + ( singleton + . ( \(GovernorParameters _ governorRedeemer) -> + testValidator + (fromJust val.forGovernorValidator) + "governor" + governorValidator + governorInputDatum + governorRedeemer + (spend governorRef) + ) + ) + (pb.governorParameters) authority = case pb.authorityTokenParameters of [] -> [] @@ -715,20 +729,20 @@ mkMockEffects useAuthScript n = effects effectsPerGroup (zip effectScripts effectMetadata) -numberOfVotesThatExceedsTheMinimumRequirement :: Integer -numberOfVotesThatExceedsTheMinimumRequirement = - untag (def @ProposalThresholds).execute + 1 +numberOfVotesThatJustMeetsTheMinimumRequirement :: Integer +numberOfVotesThatJustMeetsTheMinimumRequirement = + untag (def @ProposalThresholds).execute mkWinnerVotes :: Index -> (Winner, Integer) mkWinnerVotes idx = ( EffectAt idx - , numberOfVotesThatExceedsTheMinimumRequirement + , numberOfVotesThatJustMeetsTheMinimumRequirement ) ambiguousWinnerVotes :: (Winner, Integer) ambiguousWinnerVotes = ( All - , numberOfVotesThatExceedsTheMinimumRequirement + , numberOfVotesThatJustMeetsTheMinimumRequirement ) -------------------------------------------------------------------------------- @@ -826,6 +840,7 @@ mkValidToNextStateBundle nCosigners nEffects authScript from = gov = GovernorParameters { invalidGovernorOutputDatum = False + , governorRedeemer = MintGATs } in b { governorParameters = Just gov @@ -1065,4 +1080,47 @@ mkBadGovernorOutputDatumBundle nCosigners nEffects = } where template = mkValidFromLockedBundle nCosigners nEffects - gov = GovernorParameters True + gov = GovernorParameters True MintGATs + +mkBadGovernorRedeemerBundle :: + Word -> + Word -> + ParameterBundle +mkBadGovernorRedeemerBundle nCosigners nEffects = + template + { governorParameters = Just gov + } + where + template = mkValidFromLockedBundle nCosigners nEffects + gov = GovernorParameters False CreateProposal + +mkFastforwardToFinishBundles :: + Word -> + Word -> + [ParameterBundle] +mkFastforwardToFinishBundles nCosigners nEffects = updateTemplate <$> templates + where + templates = mkValidToFailedStateBundles nCosigners nEffects + mkMaliciousTimRange = + let lb = proposalStartingTime - 1 + dub = + 1 + + proposalStartingTime + + (def :: ProposalTimingConfig).draftTime + vub = + dub + + (def :: ProposalTimingConfig).votingTime + + (def :: ProposalTimingConfig).lockingTime + lub = + vub + + (def :: ProposalTimingConfig).executingTime + go Draft = (lb, dub) + go VotingReady = (lb, vub) + go Locked = (lb, lub) + go Finished = error "cannot advance from Finished" + in uncurry closedBoundedInterval . go + updateTemplate template = + template + { transactionTimeRange = + mkMaliciousTimRange template.proposalParameters.fromStatus + } diff --git a/agora-specs/Sample/Proposal/Cosign.hs b/agora-specs/Sample/Proposal/Cosign.hs index 7ea6601..44bc01e 100644 --- a/agora-specs/Sample/Proposal/Cosign.hs +++ b/agora-specs/Sample/Proposal/Cosign.hs @@ -40,7 +40,8 @@ import Agora.Proposal.Time ( ) import Agora.SafeMoney (GTTag) import Agora.Stake ( - ProposalLock (Cosigned, Created), + ProposalAction (Cosigned, Created), + ProposalLock (ProposalLock), StakeDatum (..), StakeRedeemer (PermitVote), ) @@ -196,7 +197,7 @@ mkStakeInputDatum ps = amount = mkStakeAmount sps.gtAmount owner = mkStakeOwner sps.stakeOwner locks = case sps.stakeOwner of - Creator -> [Created defProposalId] + Creator -> [ProposalLock defProposalId Created] _ -> [] in StakeDatum { stakedAmount = amount @@ -212,7 +213,7 @@ mkStakeOuputDatum ps = locks = if sps.dontUpdateLocks then inpDatum.lockedBy - else Cosigned defProposalId : inpDatum.lockedBy + else ProposalLock defProposalId Cosigned : inpDatum.lockedBy in inpDatum {lockedBy = locks} stakeRedeemer :: StakeRedeemer diff --git a/agora-specs/Sample/Proposal/Create.hs b/agora-specs/Sample/Proposal/Create.hs index 68af446..bcd49df 100644 --- a/agora-specs/Sample/Proposal/Create.hs +++ b/agora-specs/Sample/Proposal/Create.hs @@ -17,12 +17,19 @@ module Sample.Proposal.Create ( timeRangeNotTightParameters, timeRangeNotClosedParameters, invalidProposalStatusParameters, + fakeSSTParameters, + wrongGovernorRedeemer, + wrongGovernorRedeemer1, ) where import Agora.Governor ( Governor (..), GovernorDatum (..), - GovernorRedeemer (CreateProposal), + GovernorRedeemer ( + CreateProposal, + MintGATs, + MutateGovernor + ), ) import Agora.Proposal ( ProposalDatum (..), @@ -40,7 +47,8 @@ import Agora.Proposal.Time ( ) import Agora.SafeMoney (GTTag) import Agora.Stake ( - ProposalLock (..), + ProposalAction (Created, Voted), + ProposalLock (ProposalLock), StakeDatum (..), StakeRedeemer (PermitVote), ) @@ -63,10 +71,14 @@ import Plutarch.Context ( withValue, ) import Plutarch.Extra.AssetClass (assetClassValue) +import Plutarch.Extra.ScriptContext (validatorHashToTokenName) +import PlutusLedgerApi.V1.Value qualified as Value import PlutusLedgerApi.V2 ( Credential (PubKeyCredential), POSIXTime (POSIXTime), POSIXTimeRange, + Redeemer (Redeemer), + ToData (toBuiltinData), TxOutRef (TxOutRef), always, ) @@ -85,6 +97,7 @@ import Sample.Shared ( signer, signer2, stakeAssetClass, + stakeSymbol, stakeValidator, stakeValidatorHash, ) @@ -95,6 +108,7 @@ import Test.Util ( mkMinting, mkSpending, sortValue, + validatorHashes, ) -- | Parameters for creating a proposal. @@ -115,11 +129,15 @@ data Parameters = Parameters -- ^ Is 'TxInfo.validTimeRange' closed? , proposalStatus :: ProposalStatus -- ^ The status of the newly created proposal. + , fakeSST :: Bool + -- ^ Whether to use SST that doesn't belong to the stake validator. + , governorRedeemer :: Redeemer + -- ^ The redeemer used to spend the governor. } -------------------------------------------------------------------------------- --- | See 'GovernorDatum.maximumProposalsPerStake'. +-- | See 'GovernorDatum.maximumCreatedProposalsPerStake'. maxProposalPerStake :: Integer maxProposalPerStake = 3 @@ -143,7 +161,7 @@ alteredStakeOwner = PubKeyCredential signer2 -- | Locks the stake that the input stake already has. defLocks :: [ProposalLock] -defLocks = [Created (ProposalId 0)] +defLocks = [ProposalLock (ProposalId 0) Created] -- | The effect of the newly created proposal. defEffects :: StrictMap.Map ResultTag ProposalEffectGroup @@ -164,7 +182,7 @@ governorInputDatum = , nextProposalId = thisProposalId , proposalTimings = def , createProposalTimeRangeMaxWidth = def - , maximumProposalsPerStake = maxProposalPerStake + , maximumCreatedProposalsPerStake = maxProposalPerStake } -- | Create governor output datum given the parameters. @@ -179,7 +197,7 @@ mkGovernorOutputDatum ps = , nextProposalId = nextPid , proposalTimings = def , createProposalTimeRangeMaxWidth = def - , maximumProposalsPerStake = maxProposalPerStake + , maximumCreatedProposalsPerStake = maxProposalPerStake } -------------------------------------------------------------------------------- @@ -190,7 +208,7 @@ mkStakeInputDatum ps = let locks = if ps.createdMoreThanMaximumProposals then - Created . ProposalId + flip ProposalLock Created . ProposalId <$> take (fromInteger maxProposalPerStake) [1 ..] @@ -209,10 +227,10 @@ mkStakeOutputDatum ps = newLocks = if ps.invalidNewLocks then - [ Voted thisProposalId (ResultTag 0) - , Voted thisProposalId (ResultTag 1) + [ ProposalLock thisProposalId $ Voted (ResultTag 0) 100 + , ProposalLock thisProposalId $ Voted (ResultTag 1) 100 ] - else [Created thisProposalId] + else [ProposalLock thisProposalId Created] locks = newLocks <> inputDatum.lockedBy newOwner = mkOwner ps in inputDatum @@ -289,6 +307,30 @@ createProposal ps = builder --- + attacker = head validatorHashes + + fakeStakeBuilder = + if ps.fakeSST + then + mconcat + [ input @b $ + mconcat + [ script attacker + , withValue $ + Value.singleton + stakeSymbol + (validatorHashToTokenName attacker) + 1 + , withDatum $ + (mkStakeInputDatum ps) + { stakedAmount = 10000000000 + } + ] + ] + else mempty + + --- + governorValue = sortValue $ gst <> minAda stakeValue = sortValue $ @@ -324,7 +366,7 @@ createProposal ps = builder [ script governorValidatorHash , withValue governorValue , withDatum governorInputDatum - , withRedeemer governorRedeemer + , withRedeemer ps.governorRedeemer , withRef governorRef ] , output $ @@ -334,19 +376,39 @@ createProposal ps = builder , withDatum (mkGovernorOutputDatum ps) ] , --- - input $ - mconcat - [ script stakeValidatorHash - , withValue stakeValue - , withDatum (mkStakeInputDatum ps) - , withRef stakeRef - ] - , output $ - mconcat - [ script stakeValidatorHash - , withValue stakeValue - , withDatum (mkStakeOutputDatum ps) - ] + if ps.fakeSST + then + mconcat + [ input @b $ + mconcat + [ script attacker + , withValue $ + Value.singleton + stakeSymbol + (validatorHashToTokenName attacker) + 1 + , withDatum $ + (mkStakeInputDatum ps) + { stakedAmount = 10000000000 + } + ] + ] + else + mconcat + [ input $ + mconcat + [ script stakeValidatorHash + , withValue stakeValue + , withDatum (mkStakeInputDatum ps) + , withRef stakeRef + ] + , output $ + mconcat + [ script stakeValidatorHash + , withValue stakeValue + , withDatum (mkStakeOutputDatum ps) + ] + ] , --- output $ mconcat @@ -354,6 +416,8 @@ createProposal ps = builder , withValue proposalValue , withDatum (mkProposalOutputDatum ps) ] + , --- + fakeStakeBuilder ] -------------------------------------------------------------------------------- @@ -362,10 +426,6 @@ createProposal ps = builder stakeRedeemer :: StakeRedeemer stakeRedeemer = PermitVote --- | Spend the governor with the 'CreateProposal' redeemer. -governorRedeemer :: GovernorRedeemer -governorRedeemer = CreateProposal - -- | Mint the PST with an arbitrary redeemer. Doesn't really matter. proposalPolicyRedeemer :: () proposalPolicyRedeemer = () @@ -383,6 +443,8 @@ totallyValidParameters = , timeRangeTightEnough = True , timeRangeClosed = True , proposalStatus = Draft + , fakeSST = False + , governorRedeemer = Redeemer $ toBuiltinData CreateProposal } invalidOutputGovernorDatumParameters :: Parameters @@ -435,6 +497,24 @@ invalidProposalStatusParameters = ) [VotingReady, Locked, Finished] +fakeSSTParameters :: Parameters +fakeSSTParameters = + totallyValidParameters + { fakeSST = True + } + +wrongGovernorRedeemer :: Parameters +wrongGovernorRedeemer = + totallyValidParameters + { governorRedeemer = Redeemer $ toBuiltinData MintGATs + } + +wrongGovernorRedeemer1 :: Parameters +wrongGovernorRedeemer1 = + totallyValidParameters + { governorRedeemer = Redeemer $ toBuiltinData MutateGovernor + } + -------------------------------------------------------------------------------- {- | Create a test tree that runs the proposal minting policy, the governor @@ -467,7 +547,7 @@ mkTestTree "governor" governorValidator governorInputDatum - governorRedeemer + ps.governorRedeemer (spend governorRef) stakeTest = diff --git a/agora-specs/Sample/Proposal/PrivilegeEscalate.hs b/agora-specs/Sample/Proposal/PrivilegeEscalate.hs index 2c305de..157e609 100644 --- a/agora-specs/Sample/Proposal/PrivilegeEscalate.hs +++ b/agora-specs/Sample/Proposal/PrivilegeEscalate.hs @@ -20,9 +20,10 @@ import Agora.Proposal.Time ( ) import Agora.SafeMoney (GTTag) import Agora.Stake ( - ProposalLock ( + ProposalAction ( Voted ), + ProposalLock (ProposalLock), StakeDatum (..), StakeRedeemer (PermitVote, RetractVotes), ) @@ -128,8 +129,19 @@ mkStakeInputOutputDatums op = allStakes = take 10 $ firstStake : otherStakes + createdAt = (def :: ProposalTimingConfig).votingTime - 1 + stakeWithLock = - (\stake -> stake {lockedBy = [Voted defProposalId defResultTag]}) + ( \stake -> + stake + { lockedBy = + [ ProposalLock defProposalId $ + Voted + defResultTag + createdAt + ] + } + ) <$> allStakes in wrap op (,) allStakes stakeWithLock diff --git a/agora-specs/Sample/Proposal/Unlock.hs b/agora-specs/Sample/Proposal/Unlock.hs index 071d644..7e86ef1 100644 --- a/agora-specs/Sample/Proposal/Unlock.hs +++ b/agora-specs/Sample/Proposal/Unlock.hs @@ -12,6 +12,7 @@ module Sample.Proposal.Unlock ( SignedBy (..), TransactionParameters (..), ProposalParameters (..), + SSTOwner (..), StakeParameters (..), Validity (..), unlock, @@ -26,6 +27,8 @@ module Sample.Proposal.Unlock ( mkRemoveCreatorLockBeforeFinished, mkCreatorRetractVotes, mkChangeOutputStakeValue, + mkUseFakeStakes, + mkDisrespectCooldown, ) where -------------------------------------------------------------------------------- @@ -40,13 +43,18 @@ import Agora.Proposal ( ProposalVotes (..), ResultTag (..), ) -import Agora.Proposal.Time (ProposalStartingTime (ProposalStartingTime), ProposalTimingConfig (..)) +import Agora.Proposal.Time ( + ProposalStartingTime (ProposalStartingTime), + ProposalTimingConfig (..), + ) import Agora.SafeMoney (GTTag) import Agora.Stake ( + ProposalAction (Created, Voted), ProposalLock (..), StakeDatum (..), StakeRedeemer (RetractVotes), ) +import Data.Coerce (coerce) import Data.Default.Class (Default (def)) import Data.Map.Strict qualified as StrictMap import Data.Tagged (Tagged, untag) @@ -64,8 +72,11 @@ import Plutarch.Context ( withValue, ) import Plutarch.Extra.AssetClass (assetClassValue) +import Plutarch.Extra.ScriptContext (validatorHashToTokenName) +import PlutusLedgerApi.V1.Value qualified as Value import PlutusLedgerApi.V2 ( Credential (PubKeyCredential), + POSIXTime, PubKeyHash, TxOutRef (..), ) @@ -76,7 +87,7 @@ import Sample.Shared ( proposalAssetClass, proposalValidator, proposalValidatorHash, - stakeAssetClass, + stakeSymbol, stakeValidator, stakeValidatorHash, ) @@ -138,7 +149,7 @@ data ParameterBundle = ParameterBundle data SignedBy = Owner | Delegatee | Unknown -data TimeRange = WhileVoting | AfterVoting +data TimeRange = WhileVoting {offset :: POSIXTime} | AfterVoting data TransactionParameters = TransactionParameters { signedBy :: SignedBy @@ -162,12 +173,18 @@ data StakeRole Irrelevant deriving stock (Bounded, Enum, Show) +data SSTOwner + = StakeValidator + | Attacker + data StakeParameters = StakeParameters { numStakes :: Integer , stakeRole :: StakeRole , removeVoterLock :: Bool , removeCreatorLock :: Bool , alterOutputValue :: Bool + , sstOwner :: SSTOwner + , votingLockCreatedAt :: POSIXTime } data Validity = Validity @@ -194,14 +211,20 @@ mkStakeInputDatum ps = where stakeLocks = mkStakeLocks' ps.stakeRole - mkStakeLocks' Voter = [Voted defProposalId defVoteFor] - mkStakeLocks' Creator = [Created defProposalId] + mkStakeLocks' Voter = + [ ProposalLock defProposalId $ + Voted defVoteFor ps.votingLockCreatedAt + ] + mkStakeLocks' Creator = [ProposalLock defProposalId Created] mkStakeLocks' Both = mkStakeLocks' Voter <> mkStakeLocks' Creator mkStakeLocks' Irrelevant = let ProposalId pid = defProposalId ResultTag vid = defVoteFor - in [ Voted (ProposalId $ pid + 1) (ResultTag $ vid + 1) - , Created (ProposalId $ pid + 1) + in [ ProposalLock (ProposalId $ pid + 1) $ + Voted + (ResultTag $ vid + 1) + ps.votingLockCreatedAt + , ProposalLock (ProposalId $ pid + 1) Created ] -------------------------------------------------------------------------------- @@ -275,18 +298,21 @@ unlock ps = builder --- - sst = assetClassValue stakeAssetClass 1 + sstName = case ps.stakeParameters.sstOwner of + StakeValidator -> validatorHashToTokenName stakeValidatorHash + _ -> "" + + sst = Value.singleton stakeSymbol sstName 1 stakeInputDatum = mkStakeInputDatum ps.stakeParameters + -- TODO respect timing removeLocks v c = - filter $ - not - . ( \case - Created pid -> c && pid == defProposalId - Cosigned pid -> c && pid == defProposalId - Voted pid _ -> v && pid == defProposalId - ) + filter $ \(ProposalLock pid action) -> + pid == defProposalId + && case action of + Voted _ _ -> v + _ -> c stakeOutputDatum = stakeInputDatum @@ -342,9 +368,14 @@ unlock ps = builder ProposalStartingTime s = defStartingTime time = case ps.transactionParameters.timeRange of - WhileVoting -> - let lb = s + (def :: ProposalTimingConfig).draftTime - ub = lb + (def :: ProposalTimingConfig).votingTime + WhileVoting offset -> + let lb = + ps.stakeParameters.votingLockCreatedAt + + offset + ub = + s + + (def :: ProposalTimingConfig).draftTime + + (def :: ProposalTimingConfig).votingTime in closedBoundedInterval (lb + 1) (ub - 1) AfterVoting -> let lb = @@ -415,12 +446,22 @@ mkValidVoterRetractVotes i = , removeVoterLock = True , removeCreatorLock = False , alterOutputValue = False + , sstOwner = StakeValidator + , votingLockCreatedAt = + coerce defStartingTime + + (def :: ProposalTimingConfig).draftTime + + 1 } , transactionParameters = TransactionParameters { signedBy = Owner , timeRange = WhileVoting + { offset = + coerce + (def :: ProposalTimingConfig).minStakeVotingTime + + 5 + } } } @@ -530,10 +571,6 @@ mkCreatorRetractVotes i = template.stakeParameters { stakeRole = Creator } - , transactionParameters = - template.transactionParameters - { timeRange = WhileVoting - } } mkChangeOutputStakeValue :: Integer -> ParameterBundle @@ -545,3 +582,29 @@ mkChangeOutputStakeValue i = { alterOutputValue = True } } + +mkUseFakeStakes :: Integer -> ParameterBundle +mkUseFakeStakes i = + let template = mkValidVoterCreatorRetractVotes i + in template + { stakeParameters = + template.stakeParameters + { sstOwner = Attacker + } + } + +mkDisrespectCooldown :: Integer -> ParameterBundle +mkDisrespectCooldown i = + let template = mkValidVoterCreatorRetractVotes i + in template + { transactionParameters = + template.transactionParameters + { timeRange = + WhileVoting + { offset = + coerce + (def :: ProposalTimingConfig).minStakeVotingTime + - 5 + } + } + } diff --git a/agora-specs/Sample/Proposal/Vote.hs b/agora-specs/Sample/Proposal/Vote.hs index dd681c8..576e190 100644 --- a/agora-specs/Sample/Proposal/Vote.hs +++ b/agora-specs/Sample/Proposal/Vote.hs @@ -18,6 +18,7 @@ module Sample.Proposal.Vote ( mkTestTree, mkValidOwnerVoteBundle, mkValidDelegateeVoteBundle, + delegateeVoteWithOwnAndDelegatedStakeBundle, transparentAssets, transactionNotAuthorized, voteForNonexistentOutcome, @@ -35,6 +36,7 @@ import Agora.Proposal ( ProposalId (ProposalId), ProposalRedeemer (Vote), ProposalStatus (VotingReady), + ProposalThresholds (vote), ProposalVotes (ProposalVotes), ResultTag (ResultTag), ) @@ -44,7 +46,8 @@ import Agora.Proposal.Time ( ) import Agora.SafeMoney (GTTag) import Agora.Stake ( - ProposalLock (Voted), + ProposalAction (Voted), + ProposalLock (ProposalLock), StakeDatum (..), StakeRedeemer (Destroy, PermitVote), ) @@ -66,7 +69,7 @@ import Plutarch.Context ( withValue, ) import Plutarch.Extra.AssetClass (adaClass, assetClassValue) -import PlutusLedgerApi.V2 (Credential (PubKeyCredential), PubKeyHash) +import PlutusLedgerApi.V2 (Credential (PubKeyCredential), Interval, POSIXTime, PubKeyHash) import PlutusLedgerApi.V2.Contexts (TxOutRef (TxOutRef)) import Sample.Proposal.Shared (proposalTxRef) import Sample.Shared ( @@ -98,6 +101,7 @@ newtype VoteParameters = VoteParameters {voteFor :: ResultTag} data StakeParameters = StakeParameters { numStakes :: Integer + , mixInDelegateeAsOwner :: Bool , stakeInputParameters :: StakeInputParameters , stakeOutputParameters :: StakeOutputParameters } @@ -142,6 +146,24 @@ delegatee = pubKeyHashes !! 1 unknownSig :: PubKeyHash unknownSig = pubKeyHashes !! 2 +validTimeRangeLowerBound :: POSIXTime +validTimeRangeLowerBound = + 0 + + (def :: ProposalTimingConfig).draftTime + + 1 + +validTimeRangeUpperBound :: POSIXTime +validTimeRangeUpperBound = + validTimeRangeLowerBound + + (def :: ProposalTimingConfig).votingTime + - 2 + +validTimeRange :: Interval POSIXTime +validTimeRange = + closedBoundedInterval + validTimeRangeLowerBound + validTimeRangeUpperBound + -------------------------------------------------------------------------------- initialVotes :: StrictMap.Map ResultTag Integer @@ -194,8 +216,8 @@ mkStakeInputDatum params = , owner = PubKeyCredential stakeOwner , delegatedTo = Just (PubKeyCredential delegatee) , lockedBy = - [ Voted (ProposalId 0) (ResultTag 0) - , Voted (ProposalId 1) (ResultTag 2) + [ ProposalLock (ProposalId 0) $ Voted (ResultTag 0) 100 + , ProposalLock (ProposalId 1) $ Voted (ResultTag 2) 200 ] } @@ -224,9 +246,11 @@ vote params = <> minAda newLock = - Voted + ProposalLock proposalInputDatum.proposalId - params.voteParameters.voteFor + $ Voted + params.voteParameters.voteFor + validTimeRangeUpperBound updatedLocks = if params.stakeParameters.stakeOutputParameters.dontAddNewLock @@ -256,6 +280,16 @@ vote params = stakeRedeemer = mkStakeRedeemer params.stakeParameters.stakeOutputParameters + mixOwner i datum = + if params.stakeParameters.mixInDelegateeAsOwner + && i == 2 + then + datum + { owner = PubKeyCredential delegatee + , delegatedTo = Nothing + } + else datum + stakeBuilder :: b stakeBuilder = foldMap @@ -265,7 +299,7 @@ vote params = mconcat [ script stakeValidatorHash , withValue stakeInputValue - , withInlineDatum stakeInputDatum + , withInlineDatum $ mixOwner i stakeInputDatum , withRedeemer stakeRedeemer , withRef $ mkStakeRef numProposals' i ] @@ -276,7 +310,7 @@ vote params = mconcat [ script stakeValidatorHash , withValue stakeOutputValue - , withInlineDatum stakeOutputDatum + , withInlineDatum $ mixOwner i stakeOutputDatum ] ] ) @@ -344,13 +378,6 @@ vote params = -------------------------------------------------------------------------- - validTimeRange = - closedBoundedInterval - ((def :: ProposalTimingConfig).draftTime + 1) - ((def :: ProposalTimingConfig).votingTime - 1) - - -------------------------------------------------------------------------- - miscBuilder :: b miscBuilder = mconcat @@ -419,9 +446,10 @@ mkValidOwnerVoteBundle stakes = , stakeParameters = StakeParameters { numStakes = stakes + , mixInDelegateeAsOwner = False , stakeInputParameters = StakeInputParameters - { perStakeGTs = 114514 + { perStakeGTs = (def :: ProposalThresholds).vote } , stakeOutputParameters = StakeOutputParameters @@ -452,6 +480,16 @@ mkValidDelegateeVoteBundle stakes = } } +delegateeVoteWithOwnAndDelegatedStakeBundle :: ParameterBundle +delegateeVoteWithOwnAndDelegatedStakeBundle = + let template = mkValidDelegateeVoteBundle 5 + in template + { stakeParameters = + template.stakeParameters + { mixInDelegateeAsOwner = True + } + } + ownerVoteWithSignleStake :: ParameterBundle ownerVoteWithSignleStake = mkValidOwnerVoteBundle 1 diff --git a/agora-specs/Sample/Shared.hs b/agora-specs/Sample/Shared.hs index 9737f46..e5a7b73 100644 --- a/agora-specs/Sample/Shared.hs +++ b/agora-specs/Sample/Shared.hs @@ -12,7 +12,7 @@ module Sample.Shared ( signer, signer2, minAda, - deterministicTracingConfing, + deterministicTracingConfig, mkRedeemer, -- * Agora Scripts @@ -72,9 +72,6 @@ import Agora.Proposal.Time ( ProposalTimingConfig (..), ) import Agora.SafeMoney (GovernorSTTag, ProposalSTTag, StakeSTTag) -import Agora.Utils ( - validatorHashToTokenName, - ) import Data.Default.Class (Default (..)) import Data.Map (Map, (!)) import Data.Tagged (Tagged (..)) @@ -86,6 +83,7 @@ import Plutarch.Api.V2 ( validatorHash, ) import Plutarch.Extra.AssetClass (AssetClass (AssetClass)) +import Plutarch.Extra.ScriptContext (validatorHashToTokenName) import PlutusLedgerApi.V1.Address (scriptHashAddress) import PlutusLedgerApi.V1.Value (TokenName, Value) import PlutusLedgerApi.V1.Value qualified as Value ( @@ -123,8 +121,8 @@ import ScriptExport.ScriptInfo (runLinker) -- Plutarch compiler configauration. -- TODO: add the ability to change this value. Maybe wrap everything in a -- Reader monad? -deterministicTracingConfing :: Config -deterministicTracingConfing = Config DetTracing +deterministicTracingConfig :: Config +deterministicTracingConfig = Config DetTracing governor :: Governor governor = Governor oref gt mc @@ -144,7 +142,7 @@ agoraScripts = (fmap (view #script) . view #scripts) ( runLinker linker - (Bootstrap.agoraScripts deterministicTracingConfing) + (Bootstrap.agoraScripts deterministicTracingConfig) governor ) @@ -242,6 +240,8 @@ instance Default ProposalTimingConfig where , votingTime = 1000 , lockingTime = 2000 , executingTime = 3000 + , minStakeVotingTime = 100 + , votingTimeRangeMaxWidth = 1000000 } {- | Default value of 'Agora.Governor.GovernorDatum.createProposalTimeRangeMaxWidth'. diff --git a/agora-specs/Sample/Stake/Create.hs b/agora-specs/Sample/Stake/Create.hs index 40266df..b8eac00 100644 --- a/agora-specs/Sample/Stake/Create.hs +++ b/agora-specs/Sample/Stake/Create.hs @@ -20,8 +20,7 @@ module Sample.Stake.Create ( import Agora.Governor (Governor (gtClassRef)) import Agora.Proposal (ProposalId (ProposalId)) import Agora.SafeMoney (GTTag) -import Agora.Stake (ProposalLock (Created), StakeDatum (..)) -import Agora.Utils (validatorHashToTokenName) +import Agora.Stake (ProposalAction (Created), ProposalLock (ProposalLock), StakeDatum (..)) import Data.Semigroup (stimesMonoid) import Data.Tagged (Tagged) import Plutarch.Context ( @@ -36,6 +35,7 @@ import Plutarch.Context ( withValue, ) import Plutarch.Extra.AssetClass (assetClassValue) +import Plutarch.Extra.ScriptContext (validatorHashToTokenName) import Plutarch.Lift (PUnsafeLiftDecl (PLifted)) import PlutusLedgerApi.V1.Value qualified as Value import PlutusLedgerApi.V2 ( @@ -255,6 +255,6 @@ alreadyHasLocks = { stakedAmount = 114514 , owner = PubKeyCredential signer , delegatedTo = Nothing - , lockedBy = [Created $ ProposalId 0] + , lockedBy = [ProposalLock (ProposalId 0) Created] } } diff --git a/agora-specs/Sample/Stake/Destroy.hs b/agora-specs/Sample/Stake/Destroy.hs index 451c208..c107768 100644 --- a/agora-specs/Sample/Stake/Destroy.hs +++ b/agora-specs/Sample/Stake/Destroy.hs @@ -20,7 +20,8 @@ module Sample.Stake.Destroy ( import Agora.Proposal (ProposalId (..)) import Agora.Stake ( - ProposalLock (Created), + ProposalAction (Created), + ProposalLock (ProposalLock), StakeDatum (..), StakeRedeemer (Destroy), ) @@ -105,7 +106,7 @@ mkStakeInputDatum ps = { stakedAmount = 114514 , owner = PubKeyCredential owner , delegatedTo = Just $ PubKeyCredential delegatee - , lockedBy = [Created $ ProposalId 0 | ps.notUnlocked] + , lockedBy = [ProposalLock (ProposalId 0) Created | ps.notUnlocked] } mkStakeRef :: Int -> TxOutRef diff --git a/agora-specs/Sample/Stake/UnauthorizedMintingExploit.hs b/agora-specs/Sample/Stake/UnauthorizedMintingExploit.hs new file mode 100644 index 0000000..88dd673 --- /dev/null +++ b/agora-specs/Sample/Stake/UnauthorizedMintingExploit.hs @@ -0,0 +1,74 @@ +module Sample.Stake.UnauthorizedMintingExploit ( + Parameters (..), + exploit, + mkTestCase, +) where + +import Plutarch.Context ( + input, + mint, + normalizeValue, + output, + script, + withValue, + ) +import Plutarch.Extra.AssetClass (assetClassValue) +import Plutarch.Extra.ScriptContext (validatorHashToTokenName) +import PlutusLedgerApi.V1.Value qualified as Value +import Sample.Shared ( + minAda, + stakeAssetClass, + stakePolicy, + stakeSymbol, + stakeValidatorHash, + ) +import Test.Specification (SpecificationTree, testPolicy) +import Test.Util ( + CombinableBuilder, + mkMinting, + validatorHashes, + ) + +newtype Parameters = Parameters + { inputSST :: Int + } + +exploit :: + forall b. + CombinableBuilder b => + Parameters -> + b +exploit (Parameters inputSST) = + mconcat + [ input $ + mconcat + [ script attacker + , withValue $ + normalizeValue $ + minAda <> fakeSSTValue inputSST + ] + , mint $ fakeSSTValue $ negate inputSST + , mint sst + , output $ + mconcat + [ script stakeValidatorHash + , withValue $ + normalizeValue $ + minAda <> sst + ] + ] + where + attacker = head validatorHashes + + fakeSSTValue = + Value.singleton + stakeSymbol + (validatorHashToTokenName attacker) + . fromIntegral + + sst = assetClassValue stakeAssetClass 1 + +mkTestCase :: String -> Parameters -> SpecificationTree +mkTestCase name ps = + testPolicy False name stakePolicy () $ + mkMinting exploit ps stakeSymbol diff --git a/agora-specs/Spec/AuthorityToken.hs b/agora-specs/Spec/AuthorityToken.hs index 8d5cfc4..b169b42 100644 --- a/agora-specs/Spec/AuthorityToken.hs +++ b/agora-specs/Spec/AuthorityToken.hs @@ -10,7 +10,7 @@ Tests for Authority token functions module Spec.AuthorityToken (specs) where import Agora.AuthorityToken (singleAuthorityTokenBurned) -import Plutarch (ClosedTerm, POpaque, perror, popaque) +import Data.Tagged (Tagged (Tagged)) import Plutarch.Extra.Compile (mustCompile) import Plutarch.Unsafe (punsafeCoerce) import PlutusLedgerApi.V1 ( @@ -29,21 +29,13 @@ import PlutusLedgerApi.V1.Value qualified as Value ( singleton, ) import PlutusTx.AssocMap qualified as AssocMap (empty) +import Sample.AuthorityToken.UnauthorizedMintingExploit qualified as UnauthorizedMintingExploit import Test.Specification ( SpecificationTree, group, scriptFails, scriptSucceeds, ) -import Prelude ( - Maybe (Nothing), - PBool, - Semigroup ((<>)), - fmap, - pconstant, - pif, - ($), - ) currencySymbol :: CurrencySymbol currencySymbol = "deadbeef" @@ -54,7 +46,7 @@ mkInputs = fmap (TxInInfo (TxOutRef "" 0)) singleAuthorityTokenBurnedTest :: Value -> [TxOut] -> Script singleAuthorityTokenBurnedTest mint outs = let actual :: ClosedTerm PBool - actual = singleAuthorityTokenBurned (pconstant currencySymbol) (punsafeCoerce $ pconstant $ mkInputs outs) (pconstant mint) + actual = singleAuthorityTokenBurned (pconstant $ Tagged currencySymbol) (punsafeCoerce $ pconstant $ mkInputs outs) (pconstant mint) s :: ClosedTerm POpaque s = pif @@ -150,4 +142,15 @@ specs = ] ) ] + , group "unauthorized minting exploit" + $ map + ( UnauthorizedMintingExploit.mkTestCase "(negative test)" + . uncurry UnauthorizedMintingExploit.Parameters + ) + $ let l = [1 .. 10] + in [ (burnt, minted) + | burnt <- l + , minted <- l + , minted < burnt + ] ] diff --git a/agora-specs/Spec/Proposal.hs b/agora-specs/Spec/Proposal.hs index dd82c4f..c0624c7 100644 --- a/agora-specs/Spec/Proposal.hs +++ b/agora-specs/Spec/Proposal.hs @@ -85,6 +85,24 @@ specs = True ) Create.invalidProposalStatusParameters + , Create.mkTestTree + "fake SST" + Create.fakeSSTParameters + True + False + False + , Create.mkTestTree + "wrong governor redeemer" + Create.wrongGovernorRedeemer + False + False + True + , Create.mkTestTree + "wrong governor redeemer" + Create.wrongGovernorRedeemer1 + False + False + True ] ] , group @@ -148,6 +166,10 @@ specs = "transparent non-GT tokens" Vote.transparentAssets (Vote.Validity True True) + , Vote.mkTestTree + "Delegatee vote with own and delegated stakes in one tx" + Vote.delegateeVoteWithOwnAndDelegatedStakeBundle + (Vote.Validity True True) ] , group "illegal" @@ -327,6 +349,25 @@ specs = , forGovernorValidator = Just False , forAuthorityTokenPolicy = Just True } + , Advance.mkTestTree' + "fastforward to finished" + (\b -> unwords ["from", show b.proposalParameters.fromStatus]) + (Advance.mkFastforwardToFinishBundles cs es) + Advance.Validity + { forProposalValidator = False + , forStakeValidator = True + , forGovernorValidator = Just False + , forAuthorityTokenPolicy = Just True + } + , Advance.mkTestTree + "wrong governor redeemer" + (Advance.mkBadGovernorRedeemerBundle cs es) + Advance.Validity + { forProposalValidator = True + , forStakeValidator = True + , forGovernorValidator = Just False + , forAuthorityTokenPolicy = Just False + } ] ] , group "unlocking" $ @@ -392,6 +433,14 @@ specs = "change output stake value" (Unlock.mkChangeOutputStakeValue nStakes) (Unlock.Validity True False) + , Unlock.mkTestTree + "use fake stake" + (Unlock.mkUseFakeStakes nStakes) + (Unlock.Validity False False) + , Unlock.mkTestTree + "retract votes in cooldown" + (Unlock.mkDisrespectCooldown nStakes) + (Unlock.Validity True False) ] legalGroup = group "legal" $ map mkLegalGroup stakeCountCases diff --git a/agora-specs/Spec/Stake.hs b/agora-specs/Spec/Stake.hs index ae26e88..7f864b2 100644 --- a/agora-specs/Spec/Stake.hs +++ b/agora-specs/Spec/Stake.hs @@ -29,6 +29,7 @@ import Sample.Stake qualified as Stake ( import Sample.Stake.Create qualified as Create import Sample.Stake.Destroy qualified as Destroy import Sample.Stake.SetDelegate qualified as SetDelegate +import Sample.Stake.UnauthorizedMintingExploit qualified as UnauthorizedMintingExploit import Test.Specification ( SpecificationTree, group, @@ -179,5 +180,13 @@ specs = SetDelegate.invalidOutputStakeDatumParameters False ] + , group + "unauthorized SST minting exploit" + $ map + ( UnauthorizedMintingExploit.mkTestCase + "(negative test)" + . UnauthorizedMintingExploit.Parameters + ) + [1 .. 20] ] ] diff --git a/agora.cabal b/agora.cabal index 853032a..93107a0 100644 --- a/agora.cabal +++ b/agora.cabal @@ -143,6 +143,9 @@ common test-deps common exe-opts ghc-options: -threaded -rtsopts -with-rtsopts=-N -O0 +common test-opts + ghc-options: -threaded -rtsopts -with-rtsopts=-N -O2 + library import: lang, deps, plutarch-prelude exposed-modules: @@ -192,6 +195,7 @@ library agora-specs exposed-modules: Property.Generator Property.Governor + Sample.AuthorityToken.UnauthorizedMintingExploit Sample.Effect.GovernorMutation Sample.Effect.TreasuryWithdrawal Sample.Governor.Initialize @@ -208,6 +212,7 @@ library agora-specs Sample.Stake.Create Sample.Stake.Destroy Sample.Stake.SetDelegate + Sample.Stake.UnauthorizedMintingExploit Sample.Treasury Spec.AuthorityToken Spec.Effect.GovernorMutation @@ -222,7 +227,7 @@ library agora-specs build-depends: agora-testlib test-suite agora-test - import: lang, deps, plutarch-prelude, test-deps + import: lang, deps, plutarch-prelude, test-deps, test-opts type: exitcode-stdio-1.0 main-is: Spec.hs hs-source-dirs: agora-test diff --git a/agora/Agora/AuthorityToken.hs b/agora/Agora/AuthorityToken.hs index aeefa4a..b1bffc0 100644 --- a/agora/Agora/AuthorityToken.hs +++ b/agora/Agora/AuthorityToken.hs @@ -11,10 +11,9 @@ module Agora.AuthorityToken ( singleAuthorityTokenBurned, ) where -import Agora.Utils ( - passert, - psymbolValueOf', - ) +import Agora.Governor (PGovernorRedeemer (PMintGATs), presolveGovernorRedeemer) +import Agora.SafeMoney (AuthorityTokenTag, GovernorSTTag) +import Agora.Utils (ptag, ptaggedSymbolValueOf, ptoScottEncodingT, puntag) import Plutarch.Api.V1 ( PCredential (..), PCurrencySymbol (..), @@ -26,17 +25,16 @@ import Plutarch.Api.V2 ( KeyGuarantees, PAddress (PAddress), PMintingPolicy, - PScriptContext (PScriptContext), PScriptPurpose (PMinting), PTxInInfo (PTxInInfo), - PTxInfo (PTxInfo), PTxOut (PTxOut), ) -import Plutarch.Extra.AssetClass (PAssetClassData, ptoScottEncoding) +import Plutarch.Extra.AssetClass (PAssetClassData) +import Plutarch.Extra.Bool (passert) import "liqwid-plutarch-extra" Plutarch.Extra.List (plookupAssoc) -import Plutarch.Extra.Maybe (pfromJust) -import Plutarch.Extra.ScriptContext (pisTokenSpent) +import Plutarch.Extra.Maybe (passertPJust, pfromJust) import Plutarch.Extra.Sum (PSum (PSum)) +import Plutarch.Extra.Tagged (PTagged) import "liqwid-plutarch-extra" Plutarch.Extra.TermCont ( pguardC, pletC, @@ -44,7 +42,7 @@ import "liqwid-plutarch-extra" Plutarch.Extra.TermCont ( pmatchC, ) import Plutarch.Extra.Traversable (pfoldMap) -import Plutarch.Extra.Value (psymbolValueOf) +import Plutarch.Extra.Value (psymbolValueOf') -------------------------------------------------------------------------------- @@ -66,7 +64,7 @@ import Plutarch.Extra.Value (psymbolValueOf) @since 1.0.0 -} -authorityTokensValidIn :: forall (s :: S). Term s (PCurrencySymbol :--> PTxOut :--> PBool) +authorityTokensValidIn :: forall (s :: S). Term s (PTagged AuthorityTokenTag PCurrencySymbol :--> PTxOut :--> PBool) authorityTokensValidIn = phoistAcyclic $ plam $ \authorityTokenSym txOut'' -> unTermCont $ do PTxOut txOut' <- pmatchC txOut'' @@ -75,7 +73,7 @@ authorityTokensValidIn = phoistAcyclic $ PValue value' <- pmatchC txOut.value PMap value <- pmatchC value' pure $ - pmatch (plookupAssoc # pfstBuiltin # psndBuiltin # pdata authorityTokenSym # value) $ \case + pmatch (plookupAssoc # pfstBuiltin # psndBuiltin # pdata (puntag authorityTokenSym) # value) $ \case PJust (pfromData -> _tokenMap') -> pmatch (pfield @"credential" # address) $ \case PPubKeyCredential _ -> @@ -97,13 +95,13 @@ authorityTokensValidIn = phoistAcyclic $ -} singleAuthorityTokenBurned :: forall (keys :: KeyGuarantees) (amounts :: AmountGuarantees) (s :: S). - Term s PCurrencySymbol -> + Term s (PTagged AuthorityTokenTag PCurrencySymbol) -> Term s (PBuiltinList PTxInInfo) -> Term s (PValue keys amounts) -> Term s PBool singleAuthorityTokenBurned gatCs inputs mint = unTermCont $ do let gatAmountMinted :: Term _ PInteger - gatAmountMinted = psymbolValueOf # gatCs # mint + gatAmountMinted = ptaggedSymbolValueOf # gatCs # mint let inputsWithGAT = pfoldMap @@ -119,12 +117,13 @@ singleAuthorityTokenBurned gatCs inputs mint = unTermCont $ do $ resolved pure . pcon . PSum $ - psymbolValueOf + ptaggedSymbolValueOf # gatCs #$ pfield @"value" #$ resolved ) # inputs + pure $ foldr1 (#&&) @@ -147,35 +146,46 @@ singleAuthorityTokenBurned gatCs inputs mint = unTermCont $ do @since 0.1.0 -} -authorityTokenPolicy :: ClosedTerm (PAssetClassData :--> PMintingPolicy) +authorityTokenPolicy :: ClosedTerm (PTagged GovernorSTTag PAssetClassData :--> PMintingPolicy) authorityTokenPolicy = - plam $ \atAssetClass _redeemer ctx' -> - pmatch ctx' $ \(PScriptContext ctx') -> unTermCont $ do - ctx <- pletFieldsC @'["txInfo", "purpose"] ctx' - PTxInfo txInfo' <- pmatchC $ pfromData ctx.txInfo - txInfo <- pletFieldsC @'["inputs", "mint", "outputs"] txInfo' - let inputs = txInfo.inputs - govTokenSpent = pisTokenSpent # (ptoScottEncoding # atAssetClass) # inputs + plam $ \gstAssetClass _redeemer ctx -> unTermCont $ do + ctxF <- pletFieldsC @'["txInfo", "purpose"] ctx + txInfoF <- + pletFieldsC + @'[ "inputs" + , "mint" + , "outputs" + , "redeemers" + ] + ctxF.txInfo - PMinting ownSymbol' <- pmatchC $ pfromData ctx.purpose + PMinting ownSymbol' <- pmatchC $ pfromData ctxF.purpose - let ownSymbol = pfromData $ pfield @"_0" # ownSymbol' + let ownSymbol = pfromData $ pfield @"_0" # ownSymbol' - PPair mintedATs burntATs <- - pmatchC $ pfromJust #$ psymbolValueOf' # ownSymbol # txInfo.mint + PPair mintedATs burntATs <- + pmatchC $ pfromJust #$ psymbolValueOf' # ownSymbol # txInfoF.mint - pure $ - popaque $ - pif - (0 #< mintedATs) - ( unTermCont $ do - pguardC "No GAT burnt" $ 0 #== burntATs - pguardC "Parent token did not move in minting GATs" govTokenSpent - pguardC "All outputs only emit valid GATs" $ - pall - # plam - (authorityTokensValidIn # ownSymbol #) - # txInfo.outputs - pure $ pconstant () - ) - (passert "No GAT minted" (0 #== mintedATs) (pconstant ())) + pure $ + popaque $ + pif + (0 #< mintedATs) + ( unTermCont $ do + pguardC "No GAT burnt" $ 0 #== burntATs + let governorRedeemer = + passertPJust + # "GST should move" + #$ presolveGovernorRedeemer + # (ptoScottEncodingT # gstAssetClass) + # pfromData txInfoF.inputs + # txInfoF.redeemers + pguardC "Governor redeemr correct" $ + pcon PMintGATs #== governorRedeemer + pguardC "All outputs only emit valid GATs" $ + pall + # plam + (authorityTokensValidIn # ptag ownSymbol #) + # txInfoF.outputs + pure $ pconstant () + ) + (passert "No GAT minted" (0 #== mintedATs) (pconstant ())) diff --git a/agora/Agora/Effect.hs b/agora/Agora/Effect.hs index 0bd0a5c..c81c9bf 100644 --- a/agora/Agora/Effect.hs +++ b/agora/Agora/Effect.hs @@ -8,6 +8,7 @@ Helpers for constructing effects. module Agora.Effect (makeEffect) where import Agora.AuthorityToken (singleAuthorityTokenBurned) +import Agora.SafeMoney (AuthorityTokenTag) import Plutarch.Api.V1 ( PCurrencySymbol, ) @@ -17,6 +18,7 @@ import Plutarch.Api.V2 ( PTxOutRef, PValidator, ) +import Plutarch.Extra.Tagged (PTagged) import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pguardC, pletC, pletFieldsC, pmatchC, ptryFromC) {- | Helper "template" for creating effect validator. @@ -30,13 +32,13 @@ import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pguardC, pletC, pletFiel makeEffect :: forall (datum :: PType) (s :: S). (PTryFrom PData datum, PIsData datum) => - ( Term s PCurrencySymbol -> + ( Term s (PTagged AuthorityTokenTag PCurrencySymbol) -> Term s datum -> Term s PTxOutRef -> Term s (PAsData PTxInfo) -> Term s POpaque ) -> - Term s PCurrencySymbol -> + Term s (PTagged AuthorityTokenTag PCurrencySymbol) -> Term s PValidator makeEffect f atSymbol = plam $ \datum _redeemer ctx' -> unTermCont $ do diff --git a/agora/Agora/Effect/GovernorMutation.hs b/agora/Agora/Effect/GovernorMutation.hs index 1b10ee7..2050a28 100644 --- a/agora/Agora/Effect/GovernorMutation.hs +++ b/agora/Agora/Effect/GovernorMutation.hs @@ -25,8 +25,8 @@ import Agora.Governor ( PGovernorDatum, PGovernorRedeemer, ) -import Agora.Plutarch.Orphans () -import Agora.Utils (pfromSingleton, ptryFromRedeemer) +import Agora.SafeMoney (AuthorityTokenTag, GovernorSTTag) +import Agora.Utils (ptaggedSymbolValueOf) import Plutarch.Api.V1 (PCurrencySymbol, PValidatorHash) import Plutarch.Api.V2 ( PScriptPurpose (PSpending), @@ -38,11 +38,17 @@ import Plutarch.DataRepr ( PDataFields, ) import Plutarch.Extra.Field (pletAll, pletAllC) -import Plutarch.Extra.Maybe (passertPJust, pdnothing) +import "liqwid-plutarch-extra" Plutarch.Extra.List (ptryFromSingleton) +import Plutarch.Extra.Maybe (passertPJust, pfromJust) import Plutarch.Extra.Record (mkRecordConstr, (.=)) -import Plutarch.Extra.ScriptContext (paddressFromValidatorHash, pfromOutputDatum, pisScriptAddress) +import Plutarch.Extra.ScriptContext ( + pisScriptAddress, + ptryFromOutputDatum, + ptryFromRedeemer, + pvalidatorHashFromAddress, + ) +import Plutarch.Extra.Tagged (PTagged) import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pguardC, pletC, pletFieldsC) -import Plutarch.Extra.Value (psymbolValueOf) import Plutarch.Lift (PConstantDecl, PLifted, PUnsafeLiftDecl) import PlutusLedgerApi.V1 (TxOutRef) import PlutusTx qualified @@ -145,8 +151,8 @@ deriving anyclass instance PTryFrom PData PMutateGovernorDatum mutateGovernorValidator :: ClosedTerm ( PValidatorHash - :--> PCurrencySymbol - :--> PCurrencySymbol + :--> PTagged GovernorSTTag PCurrencySymbol + :--> PTagged AuthorityTokenTag PCurrencySymbol :--> PValidator ) mutateGovernorValidator = @@ -177,25 +183,23 @@ mutateGovernorValidator = pany # plam ( flip pletAll $ \inputF -> - let governorAddress = - paddressFromValidatorHash - # govValidatorHash - # pdnothing - - isGovernorInput = + let isGovernorInput = foldl1 (#&&) [ ptraceIfFalse "Governor UTxO should carry GST" $ - psymbolValueOf + ptaggedSymbolValueOf # gstSymbol # (pfield @"value" # inputF.resolved) #== 1 , ptraceIfFalse "Can only modify the pinned governor" $ inputF.outRef #== effectDatumF.governorRef , ptraceIfFalse "Governor validator run" $ - pfield @"address" - # inputF.resolved - #== governorAddress + let inputValidatorHash = + pfromJust + #$ pvalidatorHashFromAddress + #$ pfield @"address" + # inputF.resolved + in inputValidatorHash #== govValidatorHash ] in isGovernorInput ) @@ -216,11 +220,11 @@ mutateGovernorValidator = let governorOutput = ptrace "Only governor output is allowed" $ - pfromSingleton # pfromData txInfoF.outputs + ptryFromSingleton # pfromData txInfoF.outputs governorOutputDatum = ptrace "Resolve governor outoput datum" $ - pfromOutputDatum @PGovernorDatum + ptryFromOutputDatum @PGovernorDatum # (pfield @"datum" # governorOutput) # txInfoF.datums diff --git a/agora/Agora/Effect/NoOp.hs b/agora/Agora/Effect/NoOp.hs index 6b79621..39f50c2 100644 --- a/agora/Agora/Effect/NoOp.hs +++ b/agora/Agora/Effect/NoOp.hs @@ -8,10 +8,10 @@ A dumb effect that only burns its GAT. module Agora.Effect.NoOp (noOpValidator, PNoOp) where import Agora.Effect (makeEffect) -import Agora.Plutarch.Orphans () +import Agora.SafeMoney (AuthorityTokenTag) import Plutarch.Api.V1 (PCurrencySymbol) import Plutarch.Api.V2 (PValidator) -import Plutarch.Orphans () +import Plutarch.Extra.Tagged (PTagged) {- | Dummy datum for NoOp effect. @@ -40,7 +40,7 @@ instance PTryFrom PData (PAsData PNoOp) @since 1.0.0 -} -noOpValidator :: ClosedTerm (PCurrencySymbol :--> PValidator) +noOpValidator :: ClosedTerm (PTagged AuthorityTokenTag PCurrencySymbol :--> PValidator) noOpValidator = plam $ makeEffect $ \_ (_datum :: Term s (PAsData PNoOp)) _ _ -> popaque (pconstant ()) diff --git a/agora/Agora/Effect/TreasuryWithdrawal.hs b/agora/Agora/Effect/TreasuryWithdrawal.hs index 9501b19..4f3c1fd 100644 --- a/agora/Agora/Effect/TreasuryWithdrawal.hs +++ b/agora/Agora/Effect/TreasuryWithdrawal.hs @@ -14,8 +14,7 @@ module Agora.Effect.TreasuryWithdrawal ( ) where import Agora.Effect (makeEffect) -import Agora.Plutarch.Orphans () -import Agora.Utils (pdelete) +import Agora.SafeMoney (AuthorityTokenTag) import Plutarch.Api.V1 ( PCredential, PCurrencySymbol, @@ -35,7 +34,9 @@ import Plutarch.DataRepr ( PDataFields, ) import Plutarch.Extra.Field (pletAllC) +import "liqwid-plutarch-extra" Plutarch.Extra.List (pdeleteFirst) import Plutarch.Extra.ScriptContext (pisPubKey) +import Plutarch.Extra.Tagged (PTagged) import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pguardC, pletC, pletFieldsC) import Plutarch.Lift (PConstantDecl, PUnsafeLiftDecl (PLifted)) import PlutusLedgerApi.V1.Credential (Credential) @@ -133,7 +134,7 @@ instance PTryFrom PData PTreasuryWithdrawalDatum -} treasuryWithdrawalValidator :: forall (s :: S). - Term s (PCurrencySymbol :--> PValidator) + Term s (PTagged AuthorityTokenTag PCurrencySymbol :--> PValidator) treasuryWithdrawalValidator = plam $ makeEffect $ \_cs (datum :: Term _ PTreasuryWithdrawalDatum) effectInputRef txInfo -> unTermCont $ do @@ -178,7 +179,7 @@ treasuryWithdrawalValidator = plam $ (ptraceError "Invalid receiver") pure $ - pmatch (pdelete # credValue # receivers) $ \case + pmatch (pdeleteFirst # credValue # receivers) $ \case PJust updatedReceivers -> ptrace "Receiver output" updatedReceivers PNothing -> diff --git a/agora/Agora/Governor.hs b/agora/Agora/Governor.hs index b977d1d..e7cb192 100644 --- a/agora/Agora/Governor.hs +++ b/agora/Agora/Governor.hs @@ -21,6 +21,7 @@ module Agora.Governor ( pgetNextProposalId, getNextProposalId, pisGovernorDatumValid, + presolveGovernorRedeemer, ) where import Agora.Aeson.Orphans () @@ -39,20 +40,33 @@ import Agora.Proposal.Time ( pisMaxTimeRangeWidthValid, pisProposalTimingConfigValid, ) -import Agora.SafeMoney (GTTag) +import Agora.SafeMoney (GTTag, GovernorSTTag) import Data.Aeson qualified as Aeson import Data.Tagged (Tagged) +import Optics.TH (makeFieldLabelsNoPrefix) +import Plutarch.Api.V1.Scripts (PRedeemer) +import Plutarch.Api.V2 (KeyGuarantees (Unsorted), PMap, PScriptPurpose (PSpending), PTxInInfo) import Plutarch.DataRepr ( DerivePConstantViaData (DerivePConstantViaData), PDataFields, ) -import Plutarch.Extra.AssetClass (AssetClass) +import Plutarch.Extra.AssetClass (AssetClass, PAssetClass) +import Plutarch.Extra.Bind (PBind ((#>>=))) +import Plutarch.Extra.Field (pletAll) +import Plutarch.Extra.Function (pflip) +import Plutarch.Extra.Functor (PFunctor (pfmap)) import Plutarch.Extra.IsData ( DerivePConstantViaEnum (DerivePConstantEnum), EnumIsData (EnumIsData), PlutusTypeEnumData, ) +import "liqwid-plutarch-extra" Plutarch.Extra.List (pfindJust) +import Plutarch.Extra.Maybe (pjust, pnothing) +import Plutarch.Extra.Record (mkRecordConstr, (.=)) +import Plutarch.Extra.ScriptContext (ptryFromRedeemer) +import Plutarch.Extra.Tagged (PTagged) import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pletFieldsC) +import Plutarch.Extra.Value (passetClassValueOfT) import Plutarch.Lift (PConstantDecl, PUnsafeLiftDecl (PLifted)) import PlutusLedgerApi.V1 (TxOutRef) import PlutusTx qualified @@ -73,9 +87,8 @@ data GovernorDatum = GovernorDatum -- 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. + , maximumCreatedProposalsPerStake :: Integer + -- ^ The maximum number of proposals created by any given stakes. } deriving stock ( -- | @since 0.1.0 @@ -84,6 +97,9 @@ data GovernorDatum = GovernorDatum Generic ) +-- | @since 0.2.1 +makeFieldLabelsNoPrefix ''GovernorDatum + -- | @since 0.1.0 PlutusTx.makeIsDataIndexed ''GovernorDatum [('GovernorDatum, 0)] @@ -149,6 +165,8 @@ data Governor = Governor Aeson.FromJSON ) +makeFieldLabelsNoPrefix ''Governor + -------------------------------------------------------------------------------- {- | Plutarch-level datum for the Governor script. @@ -164,7 +182,7 @@ newtype PGovernorDatum (s :: S) = PGovernorDatum , "nextProposalId" ':= PProposalId , "proposalTimings" ':= PProposalTimingConfig , "createProposalTimeRangeMaxWidth" ':= PMaxTimeRangeWidth - , "maximumProposalsPerStake" ':= PInteger + , "maximumCreatedProposalsPerStake" ':= PInteger ] ) } @@ -181,6 +199,8 @@ newtype PGovernorDatum (s :: S) = PGovernorDatum PDataFields , -- | @since 0.1.0 PEq + , -- | @since 0.2.1 + PShow ) -- | @since 0.2.0 @@ -277,3 +297,53 @@ pisGovernorDatumValid = phoistAcyclic $ , ptraceIfFalse "time range valid" $ pisMaxTimeRangeWidthValid # datumF.createProposalTimeRangeMaxWidth ] + +{- | Find the governor input and resolve the corresponding governor redeemer, + given the assetclass of GST. + + @since 1.0.0 +-} +presolveGovernorRedeemer :: + forall (s :: S). + Term + s + ( PTagged GovernorSTTag PAssetClass + :--> PBuiltinList PTxInInfo + :--> PMap 'Unsorted PScriptPurpose PRedeemer + :--> PMaybe PGovernorRedeemer + ) +presolveGovernorRedeemer = phoistAcyclic $ + plam $ \gstClass inputs redeemers -> + let governorInputRef = + pfindJust + # plam + ( flip pletAll $ \inputF -> + let value = pfield @"value" # inputF.resolved + isGovernorInput = + passetClassValueOfT + # gstClass + # value + #== 1 + in pif + isGovernorInput + (pjust # inputF.outRef) + pnothing + ) + # inputs + + governorScriptPurpose = + pfmap + # plam + ( \ref -> + mkRecordConstr + PSpending + (#_0 .= ref) + ) + # governorInputRef + + governorRedeemer = + governorScriptPurpose + #>>= pflip + # ptryFromRedeemer @(PAsData PGovernorRedeemer) + # redeemers + in pfmap # plam pfromData # governorRedeemer diff --git a/agora/Agora/Governor/Scripts.hs b/agora/Agora/Governor/Scripts.hs index 1c09ae1..bbe92a0 100644 --- a/agora/Agora/Governor/Scripts.hs +++ b/agora/Agora/Governor/Scripts.hs @@ -35,41 +35,42 @@ import Agora.Proposal ( pneutralOption, pwinner, ) -import Agora.Proposal.Time (validateProposalStartingTime) +import Agora.Proposal.Time (pvalidateProposalStartingTime) +import Agora.SafeMoney (AuthorityTokenTag, GovernorSTTag, ProposalSTTag, StakeSTTag) import Agora.Stake ( pnumCreatedProposals, presolveStakeInputDatum, ) -import Agora.Utils ( - plistEqualsBy, - pscriptHashToTokenName, - ) -import Plutarch.Api.V1 (PCurrencySymbol) +import Agora.Utils (ptaggedSymbolValueOf, ptoScottEncodingT, puntag) +import Data.Function (on) +import Plutarch.Api.V1 (PCurrencySymbol, PValidatorHash) import Plutarch.Api.V1.AssocMap (plookup) import Plutarch.Api.V1.AssocMap qualified as AssocMap import Plutarch.Api.V2 ( - PAddress, PMintingPolicy, PScriptPurpose (PMinting, PSpending), PTxOut, PTxOutRef, PValidator, ) -import Plutarch.Extra.AssetClass (PAssetClassData, passetClass, ptoScottEncoding) +import Plutarch.Extra.AssetClass (PAssetClassData, passetClass) import Plutarch.Extra.Field (pletAll, pletAllC) -import "liqwid-plutarch-extra" Plutarch.Extra.List (pfindJust, pmapMaybe) +import "liqwid-plutarch-extra" Plutarch.Extra.List (pfindJust, plistEqualsBy, pmapMaybe) import "liqwid-plutarch-extra" Plutarch.Extra.Map (pkeys, ptryLookup) -import Plutarch.Extra.Maybe (passertPJust, pjust, pmaybe, pmaybeData, pnothing) -import Plutarch.Extra.Ord (psort) +import Plutarch.Extra.Maybe (passertPJust, pfromJust, pjust, pmaybeData, pnothing) +import Plutarch.Extra.Ord (POrdering (..), pcompareBy, pfromOrd, psort) import Plutarch.Extra.Record (mkRecordConstr, (.&), (.=)) import Plutarch.Extra.ScriptContext ( pfindTxInByTxOutRef, - pfromDatumHash, - pfromOutputDatum, pisUTXOSpent, pscriptHashFromAddress, + pscriptHashToTokenName, + ptryFromDatumHash, + ptryFromOutputDatum, + pvalidatorHashFromAddress, pvalueSpent, ) +import Plutarch.Extra.Tagged (PTagged) import "liqwid-plutarch-extra" Plutarch.Extra.TermCont ( pguardC, pletC, @@ -153,7 +154,7 @@ governorPolicy = governorDatum = ptrace "Resolve governor datum" $ - pfromOutputDatum @PGovernorDatum + ptryFromOutputDatum @PGovernorDatum # txOutF.datum # txInfoF.datums in pif isGovernorUTxO (pjust # governorDatum) pnothing @@ -263,15 +264,15 @@ governorPolicy = governorValidator :: -- | Lazy precompiled scripts. ClosedTerm - ( PAddress - :--> PAssetClassData - :--> PCurrencySymbol - :--> PCurrencySymbol - :--> PCurrencySymbol + ( PValidatorHash + :--> PTagged StakeSTTag PAssetClassData + :--> PTagged GovernorSTTag PCurrencySymbol + :--> PTagged ProposalSTTag PCurrencySymbol + :--> PTagged AuthorityTokenTag PCurrencySymbol :--> PValidator ) governorValidator = - plam $ \proposalValidatorAddress sstClass gstSymbol pstSymbol atSymbol datum redeemer ctx -> unTermCont $ do + plam $ \proposalValidatorHash sstClass gstSymbol pstSymbol atSymbol datum redeemer ctx -> unTermCont $ do ctxF <- pletAllC ctx txInfo <- pletC $ pfromData ctxF.txInfo txInfoF <- @@ -316,14 +317,16 @@ governorValidator = foldl1 (#&&) [ ptraceIfFalse "Own by governor validator" $ - outputF.address #== governorInputF.address + ((#==) `on` (pvalidatorHashFromAddress #)) + outputF.address + governorInputF.address , ptraceIfFalse "Has governor ST" $ - psymbolValueOf # gstSymbol # outputF.value #== 1 + ptaggedSymbolValueOf # gstSymbol # outputF.value #== 1 ] datum = ptrace "Resolve governor datum" $ - pfromOutputDatum @PGovernorDatum + ptryFromOutputDatum @PGovernorDatum # outputF.datum # txInfoF.datums in pif @@ -335,22 +338,24 @@ governorValidator = ---------------------------------------------------------------------------- + pstClass <- pletC $ passetClass # pto pstSymbol # pconstant "" + getProposalDatum :: Term _ (PTxOut :--> PMaybe PProposalDatum) <- pletC $ plam $ flip (pletFields @'["value", "datum", "address"]) $ \txOutF -> let isProposalUTxO = - txOutF.address - #== pdata proposalValidatorAddress - #&& psymbolValueOf - # pstSymbol + (pfromJust #$ pvalidatorHashFromAddress # pfromData txOutF.address) + #== proposalValidatorHash + #&& passetClassValueOf + # pstClass # txOutF.value #== 1 proposalDatum = ptrace "Resolve proposal output datum" $ pfromData $ - pfromOutputDatum + ptryFromOutputDatum # txOutF.datum # txInfoF.datums in pif isProposalUTxO (pjust # proposalDatum) pnothing @@ -378,8 +383,8 @@ governorValidator = .= governorInputDatumF.proposalTimings .& #createProposalTimeRangeMaxWidth .= governorInputDatumF.createProposalTimeRangeMaxWidth - .& #maximumProposalsPerStake - .= governorInputDatumF.maximumProposalsPerStake + .& #maximumCreatedProposalsPerStake + .= governorInputDatumF.maximumCreatedProposalsPerStake ) pguardC "Only next proposal id gets advanced" $ @@ -388,16 +393,7 @@ governorValidator = -- Check that exactly one proposal token is being minted. pguardC "Exactly one proposal token must be minted" $ - let vMap = pfromData $ pto txInfoF.mint - tnMap = plookup # pstSymbol # vMap - -- Ada and PST - onlyPST = plength # pto vMap #== 2 - onePST = - pmaybe - # pconstant False - # plam (#== AssocMap.psingleton # pconstant "" # 1) - # tnMap - in onlyPST #&& onePST + passetClassValueOf # pstClass # txInfoF.mint #== 1 -- Check that a stake is spent to create the propsal, -- and the value it contains meets the requirement. @@ -407,7 +403,7 @@ governorValidator = # "Stake input should present" #$ pfindJust # ( presolveStakeInputDatum - # (ptoScottEncoding # sstClass) + # (ptoScottEncodingT # sstClass) # txInfoF.datums ) # pfromData txInfoF.inputs @@ -417,7 +413,7 @@ governorValidator = pguardC "Proposals created by the stake must not exceed the limit" $ pnumCreatedProposals # stakeInputDatumF.lockedBy - #< governorInputDatumF.maximumProposalsPerStake + #< governorInputDatumF.maximumCreatedProposalsPerStake let gtThreshold = pfromData $ @@ -425,7 +421,7 @@ governorValidator = # governorInputDatumF.proposalThresholds pguardC "Require minimum amount of GTs" $ - gtThreshold #< stakeInputDatumF.stakedAmount + gtThreshold #<= stakeInputDatumF.stakedAmount -- Check that the newly minted PST is sent to the proposal validator, -- and the datum it carries is legal. @@ -457,7 +453,7 @@ governorValidator = , ptraceIfFalse "cosigners correct" $ plistEquals # pfromData proposalOutputDatumF.cosigners # expectedCosigners , ptraceIfFalse "starting time valid" $ - validateProposalStartingTime + pvalidateProposalStartingTime # governorInputDatumF.createProposalTimeRangeMaxWidth # txInfoF.validRange # proposalOutputDatumF.startingTime @@ -478,7 +474,7 @@ governorValidator = -- Filter out proposal inputs and ouputs using PST and the address of proposal validator. pguardC "The governor can only process one proposal at a time" $ - (psymbolValueOf # pstSymbol #$ pvalueSpent # txInfoF.inputs) #== 1 + (ptaggedSymbolValueOf # pstSymbol #$ pvalueSpent # txInfoF.inputs) #== 1 let proposalInputDatum = passertPJust @@ -510,14 +506,13 @@ governorValidator = ( \output -> unTermCont $ do outputF <- pletFieldsC @'["address", "datum", "value"] output - let isAuthorityUTxO = - psymbolValueOf + let atAmount = + ptaggedSymbolValueOf # atSymbol # outputF.value - #== 1 handleAuthorityUTxO = - unTermCont $ do + do receiverScriptHash <- pletC $ passertPJust @@ -538,7 +533,7 @@ governorValidator = # pconstant "" # plam (pscriptHashToTokenName . pfromData) # effect.scriptHash - gatAssetClass = passetClass # atSymbol # tagToken + gatAssetClass = passetClass # puntag atSymbol # tagToken valueGATCorrect = passetClassValueOf # gatAssetClass @@ -546,7 +541,7 @@ governorValidator = #== 1 let hasCorrectDatum = - effect.datumHash #== pfromDatumHash # outputF.datum + effect.datumHash #== ptryFromDatumHash # outputF.datum pguardC "Authority output valid" $ foldr1 @@ -556,19 +551,27 @@ governorValidator = , ptraceIfFalse "Value correctly encodes Auth Check script" valueGATCorrect ] - pure receiverScriptHash + pure $ pjust # receiverScriptHash - pure $ - pif - isAuthorityUTxO - (pjust # handleAuthorityUTxO) - pnothing + pmatchC + ( pcompareBy + # pfromOrd + # atAmount + # 1 + ) + >>= \case + -- atAmount == 1 + PEQ -> handleAuthorityUTxO + -- atAmount < 1 + PLT -> pure pnothing + -- atAmount > 1 + PGT -> pure $ ptraceError "More than one GAT in one UTxO" ) -- The sorted hashes of all the GAT receivers. actualReceivers = psort - #$ pmapMaybe + #$ pmapMaybe @PList # getReceiverScriptHash # pfromData txInfoF.outputs diff --git a/agora/Agora/Linker.hs b/agora/Agora/Linker.hs index dbd30cf..aa17905 100644 --- a/agora/Agora/Linker.hs +++ b/agora/Agora/Linker.hs @@ -3,13 +3,14 @@ module Agora.Linker (linker, AgoraScriptInfo (..)) where import Agora.Governor (Governor (gstOutRef, gtClassRef, maximumCosigners)) -import Agora.Utils (validatorHashToAddress, validatorHashToTokenName) +import Agora.SafeMoney (AuthorityTokenTag, GTTag, GovernorSTTag, ProposalSTTag, StakeSTTag) import Data.Aeson qualified as Aeson import Data.Map (fromList) -import Data.Tagged (untag) +import Data.Tagged (Tagged (Tagged)) import Plutarch.Api.V2 (mintingPolicySymbol, validatorHash) import Plutarch.Extra.AssetClass (AssetClass (AssetClass)) -import PlutusLedgerApi.V1 (Address, CurrencySymbol, TxOutRef, ValidatorHash) +import Plutarch.Extra.ScriptContext (validatorHashToTokenName) +import PlutusLedgerApi.V1 (CurrencySymbol, TxOutRef, ValidatorHash) import Ply ( ScriptRole (MintingPolicyRole, ValidatorRole), toMintingPolicy, @@ -30,10 +31,10 @@ import Prelude hiding ((#)) @since 1.0.0 -} data AgoraScriptInfo = AgoraScriptInfo - { governorAssetClass :: AssetClass - , authorityTokenSymbol :: CurrencySymbol - , proposalAssetClass :: AssetClass - , stakeAssetClass :: AssetClass + { governorAssetClass :: Tagged GovernorSTTag AssetClass + , authorityTokenSymbol :: Tagged AuthorityTokenTag CurrencySymbol + , proposalAssetClass :: Tagged ProposalSTTag AssetClass + , stakeAssetClass :: Tagged StakeSTTag AssetClass , governor :: Governor } deriving stock (Generic, Show) @@ -45,28 +46,86 @@ data AgoraScriptInfo = AgoraScriptInfo -} linker :: Linker Governor (ScriptExport AgoraScriptInfo) linker = do - govPol <- fetchTS @MintingPolicyRole @'[TxOutRef] "agora:governorPolicy" - govVal <- fetchTS @ValidatorRole @'[Address, AssetClass, CurrencySymbol, CurrencySymbol, CurrencySymbol] "agora:governorValidator" - stkPol <- fetchTS @MintingPolicyRole @'[AssetClass] "agora:stakePolicy" - stkVal <- fetchTS @ValidatorRole @'[CurrencySymbol, AssetClass, AssetClass] "agora:stakeValidator" - prpPol <- fetchTS @MintingPolicyRole @'[AssetClass] "agora:proposalPolicy" - prpVal <- fetchTS @ValidatorRole @'[AssetClass, CurrencySymbol, CurrencySymbol, Integer] "agora:proposalValidator" - treVal <- fetchTS @ValidatorRole @'[CurrencySymbol] "agora:treasuryValidator" - atkPol <- fetchTS @MintingPolicyRole @'[AssetClass] "agora:authorityTokenPolicy" - noOpVal <- fetchTS @ValidatorRole @'[CurrencySymbol] "agora:noOpValidator" - treaWithdrawalVal <- fetchTS @ValidatorRole @'[CurrencySymbol] "agora:treasuryWithdrawalValidator" - mutateGovVal <- fetchTS @ValidatorRole @'[ValidatorHash, CurrencySymbol, CurrencySymbol] "agora:mutateGovernorValidator" + govPol <- + fetchTS + @MintingPolicyRole + @'[TxOutRef] + "agora:governorPolicy" + govVal <- + fetchTS + @ValidatorRole + @'[ ValidatorHash + , Tagged StakeSTTag AssetClass + , Tagged GovernorSTTag CurrencySymbol + , Tagged ProposalSTTag CurrencySymbol + , Tagged AuthorityTokenTag CurrencySymbol + ] + "agora:governorValidator" + stkPol <- + fetchTS + @MintingPolicyRole + @'[Tagged GTTag AssetClass] + "agora:stakePolicy" + stkVal <- + fetchTS + @ValidatorRole + @'[ Tagged StakeSTTag CurrencySymbol + , Tagged ProposalSTTag AssetClass + , Tagged GTTag AssetClass + ] + "agora:stakeValidator" + prpPol <- + fetchTS @MintingPolicyRole + @'[Tagged GovernorSTTag AssetClass] + "agora:proposalPolicy" + prpVal <- + fetchTS + @ValidatorRole + @'[ Tagged StakeSTTag AssetClass + , Tagged GovernorSTTag CurrencySymbol + , Tagged ProposalSTTag CurrencySymbol + , Integer + ] + "agora:proposalValidator" + treVal <- + fetchTS + @ValidatorRole + @'[Tagged AuthorityTokenTag CurrencySymbol] + "agora:treasuryValidator" + atkPol <- + fetchTS + @MintingPolicyRole + @'[Tagged GovernorSTTag AssetClass] + "agora:authorityTokenPolicy" + noOpVal <- + fetchTS + @ValidatorRole + @'[Tagged AuthorityTokenTag CurrencySymbol] + "agora:noOpValidator" + treaWithdrawalVal <- + fetchTS + @ValidatorRole + @'[Tagged AuthorityTokenTag CurrencySymbol] + "agora:treasuryWithdrawalValidator" + mutateGovVal <- + fetchTS + @ValidatorRole + @'[ ValidatorHash + , Tagged GovernorSTTag CurrencySymbol + , Tagged AuthorityTokenTag CurrencySymbol + ] + "agora:mutateGovernorValidator" governor <- getParam let govPol' = govPol # governor.gstOutRef govVal' = govVal - # propValAddress - # sstAssetClass - # gstSymbol - # pstSymbol - # atSymbol + # propValHash + # Tagged sstAssetClass + # Tagged gstSymbol + # Tagged pstSymbol + # Tagged atSymbol gstSymbol = mintingPolicySymbol $ toMintingPolicy @@ -75,34 +134,40 @@ linker = do AssetClass gstSymbol "" govValHash = validatorHash $ toValidator govVal' - at = gstAssetClass - atPol' = atkPol # at + atPol' = atkPol # Tagged gstAssetClass atSymbol = mintingPolicySymbol $ toMintingPolicy atPol' - propPol' = prpPol # gstAssetClass + propPol' = prpPol # Tagged gstAssetClass propVal' = prpVal - # sstAssetClass - # gstSymbol - # pstSymbol + # Tagged sstAssetClass + # Tagged gstSymbol + # Tagged pstSymbol # governor.maximumCosigners - propValAddress = - validatorHashToAddress $ validatorHash $ toValidator propVal' + propValHash = validatorHash $ toValidator propVal' pstSymbol = mintingPolicySymbol $ toMintingPolicy propPol' pstAssetClass = AssetClass pstSymbol "" - stakPol' = stkPol # untag governor.gtClassRef - stakVal' = stkVal # sstSymbol # pstAssetClass # untag governor.gtClassRef + stakPol' = stkPol # governor.gtClassRef + stakVal' = + stkVal + # Tagged sstSymbol + # Tagged pstAssetClass + # governor.gtClassRef sstSymbol = mintingPolicySymbol $ toMintingPolicy stakPol' stakValTokenName = validatorHashToTokenName $ validatorHash $ toValidator stakVal' sstAssetClass = AssetClass sstSymbol stakValTokenName - treaVal' = treVal # atSymbol + treaVal' = treVal # Tagged atSymbol - noOpVal' = noOpVal # atSymbol - treaWithdrawalVal' = treaWithdrawalVal # atSymbol - mutateGovVal' = mutateGovVal # govValHash # gstSymbol # atSymbol + noOpVal' = noOpVal # Tagged atSymbol + treaWithdrawalVal' = treaWithdrawalVal # Tagged atSymbol + mutateGovVal' = + mutateGovVal + # govValHash + # Tagged gstSymbol + # Tagged atSymbol return $ ScriptExport @@ -122,10 +187,10 @@ linker = do ] , information = AgoraScriptInfo - { governorAssetClass = gstAssetClass - , authorityTokenSymbol = atSymbol - , proposalAssetClass = pstAssetClass - , stakeAssetClass = sstAssetClass + { governorAssetClass = Tagged gstAssetClass + , authorityTokenSymbol = Tagged atSymbol + , proposalAssetClass = Tagged pstAssetClass + , stakeAssetClass = Tagged sstAssetClass , governor = governor } } diff --git a/agora/Agora/Plutarch/Orphans.hs b/agora/Agora/Plutarch/Orphans.hs index bf706d7..6cb102e 100644 --- a/agora/Agora/Plutarch/Orphans.hs +++ b/agora/Agora/Plutarch/Orphans.hs @@ -6,10 +6,14 @@ import Plutarch.Lift (PConstantDecl (..), PUnsafeLiftDecl (PLifted)) import Data.Bifunctor (Bifunctor (bimap)) import Data.Map.Strict qualified as StrictMap +import Data.Tagged (Tagged (Tagged)) import Data.Traversable (for) import Plutarch.Api.V1 (KeyGuarantees (Sorted), PMap) +import Plutarch.Extra.Tagged (PTagged) import PlutusTx qualified import PlutusTx.AssocMap qualified as AssocMap +import Ply (PlyArg) +import Ply.Plutarch.Class (PlyArgOf) -- | @since 1.0.0 instance @@ -74,3 +78,9 @@ instance isSorted [] = True isSorted [_] = True isSorted (x : y : xs) = x < y && isSorted (y : xs) + +-- | @since 1.0.0 +type instance PlyArgOf (PTagged tag a) = Tagged tag (PlyArgOf a) + +-- | @since 1.0.0 +deriving newtype instance PlyArg a => PlyArg (Tagged tag a) diff --git a/agora/Agora/Proposal.hs b/agora/Agora/Proposal.hs index ab289ca..b84f549 100644 --- a/agora/Agora/Proposal.hs +++ b/agora/Agora/Proposal.hs @@ -162,7 +162,7 @@ newtype ResultTag = ResultTag {getResultTag :: Integer} data ProposalStatus = -- | A draft proposal represents a proposal that has yet to be realized. -- - -- In effect, this means one which didn't have enough LQ to be a full + -- In effect, this means one which didn't have enough GT to be a full -- proposal, and needs cosigners to enable that to happen. This is -- similar to a "temperature check", but only useful if multiple people -- want to pool governance tokens together. If the proposal doesn't get to @@ -579,6 +579,8 @@ newtype PProposalThresholds (s :: S) = PProposalThresholds PIsData , -- | @since 0.1.0 PDataFields + , -- | @since 0.2.1 + PShow ) -- | @since 0.2.0 diff --git a/agora/Agora/Proposal/Scripts.hs b/agora/Agora/Proposal/Scripts.hs index 944112d..1d42121 100644 --- a/agora/Agora/Proposal/Scripts.hs +++ b/agora/Agora/Proposal/Scripts.hs @@ -10,7 +10,7 @@ module Agora.Proposal.Scripts ( proposalPolicy, ) where -import Agora.Governor (PGovernorRedeemer (PCreateProposal)) +import Agora.Governor (PGovernorRedeemer (PCreateProposal), presolveGovernorRedeemer) import Agora.Proposal ( PProposalDatum (PProposalDatum), PProposalRedeemer (PAdvanceProposal, PCosign, PUnlockStake, PVote), @@ -23,10 +23,12 @@ import Agora.Proposal ( import Agora.Proposal.Time ( PPeriod (PDraftingPeriod, PExecutingPeriod, PLockingPeriod, PVotingPeriod), PTimingRelation (PAfter, PWithin), - currentProposalTime, + pcurrentProposalTime, pgetRelation, pisWithin, + psatisfyMaximumWidth, ) +import Agora.SafeMoney (GovernorSTTag, ProposalSTTag, StakeSTTag) import Agora.Stake ( PStakeDatum, pextractVoteOption, @@ -35,13 +37,8 @@ import Agora.Stake ( pisVoter, presolveStakeInputDatum, ) -import Agora.Utils ( - pfromSingleton, - pinsertUniqueBy, - plistEqualsBy, - pmapMaybe, - ptryFromRedeemer, - ) +import Agora.Utils (ptaggedSymbolValueOf, ptoScottEncodingT) +import Data.Function (on) import Plutarch.Api.V1 (PCredential, PCurrencySymbol) import Plutarch.Api.V1.AssocMap (plookup) import Plutarch.Api.V2 ( @@ -52,11 +49,15 @@ import Plutarch.Api.V2 ( ) import Plutarch.Extra.AssetClass ( PAssetClassData, - ptoScottEncoding, ) import Plutarch.Extra.Category (PCategory (pidentity)) import Plutarch.Extra.Field (pletAll, pletAllC) -import "liqwid-plutarch-extra" Plutarch.Extra.List (pfindJust) +import "liqwid-plutarch-extra" Plutarch.Extra.List ( + pfindJust, + plistEqualsBy, + pmapMaybe, + ptryFromSingleton, + ) import "plutarch-extra" Plutarch.Extra.Map (pupdate) import Plutarch.Extra.Maybe ( passertPJust, @@ -66,13 +67,15 @@ import Plutarch.Extra.Maybe ( pmaybe, pnothing, ) -import Plutarch.Extra.Ord (pfromOrdBy, psort) +import Plutarch.Extra.Ord (pfromOrdBy, pinsertUniqueBy, psort) import Plutarch.Extra.Record (mkRecordConstr, (.&), (.=)) import Plutarch.Extra.ScriptContext ( pfindTxInByTxOutRef, - pfromOutputDatum, + ptryFromOutputDatum, + pvalidatorHashFromAddress, ) import Plutarch.Extra.Sum (PSum (PSum)) +import Plutarch.Extra.Tagged (PTagged) import "liqwid-plutarch-extra" Plutarch.Extra.TermCont ( pguardC, pletC, @@ -80,8 +83,9 @@ import "liqwid-plutarch-extra" Plutarch.Extra.TermCont ( pmatchC, ptryFromC, ) +import Plutarch.Extra.Time (PCurrentTime) import Plutarch.Extra.Traversable (pfoldMap) -import Plutarch.Extra.Value (passetClassValueOf, psymbolValueOf) +import Plutarch.Extra.Value (psymbolValueOf') import Plutarch.Unsafe (punsafeCoerce) {- | Policy for Proposals. @@ -109,7 +113,7 @@ import Plutarch.Unsafe (punsafeCoerce) @since 1.0.0 -} -proposalPolicy :: ClosedTerm (PAssetClassData :--> PMintingPolicy) +proposalPolicy :: ClosedTerm (PTagged GovernorSTTag PAssetClassData :--> PMintingPolicy) proposalPolicy = plam $ \gstAssetClass _redeemer ctx -> unTermCont $ do ctxF <- pletAllC ctx @@ -117,44 +121,25 @@ proposalPolicy = PMinting ((pfield @"_0" #) -> ownSymbol) <- pmatchC $ pfromData ctxF.purpose - let mintedProposalST = - psymbolValueOf + pguardC "Minted exactly one proposal ST" + $ pmatch + ( pfromJust + #$ psymbolValueOf' # ownSymbol # txInfoF.mint + ) + $ \(PPair minted burnt) -> + minted + #== 1 + #&& ptraceIfFalse "Burning a proposal is not supported" (burnt #== 0) - pguardC "Minted exactly one proposal ST" $ - mintedProposalST #== 1 - - let governorInputRef = + let governorRedeemer = passertPJust # "GST should move" - #$ pfindJust - # plam - ( flip pletAll $ \inputF -> - let value = pfield @"value" # inputF.resolved - isGovernorInput = - passetClassValueOf - # (ptoScottEncoding # gstAssetClass) - # value - #== 1 - in pif - isGovernorInput - (pjust # inputF.outRef) - pnothing - ) + #$ presolveGovernorRedeemer + # (ptoScottEncodingT # gstAssetClass) # pfromData txInfoF.inputs - - governorScriptPurpose = - mkRecordConstr - PSpending - (#_0 .= governorInputRef) - - governorRedeemer = - pfromData $ - pfromJust - #$ ptryFromRedeemer @(PAsData PGovernorRedeemer) - # governorScriptPurpose - # txInfoF.redeemers + # txInfoF.redeemers pguardC "Govenor redeemer correct" $ pcon PCreateProposal #== governorRedeemer @@ -239,9 +224,9 @@ instance DerivePlutusType PStakeInputsContext where -} proposalValidator :: ClosedTerm - ( PAssetClassData - :--> PCurrencySymbol - :--> PCurrencySymbol + ( PTagged StakeSTTag PAssetClassData + :--> PTagged GovernorSTTag PCurrencySymbol + :--> PTagged ProposalSTTag PCurrencySymbol :--> PInteger :--> PValidator ) @@ -300,16 +285,18 @@ proposalValidator = foldl1 (#&&) [ ptraceIfFalse "Own by proposal validator" $ - outputF.address #== proposalInputF.address + ((#==) `on` (pvalidatorHashFromAddress #)) + outputF.address + proposalInputF.address , ptraceIfFalse "Has proposal ST" $ - psymbolValueOf # pstSymbol # outputF.value #== 1 + ptaggedSymbolValueOf # pstSymbol # outputF.value #== 1 ] handleProposalUTxO = -- Using inline datum to avoid O(n^2) lookup. pfromData $ ptrace "Resolve proposal datum" $ - pfromOutputDatum @(PAsData PProposalDatum) + ptryFromOutputDatum @(PAsData PProposalDatum) # outputF.datum # txInfoF.datums in pif @@ -321,17 +308,23 @@ proposalValidator = -------------------------------------------------------------------------- + currentTime <- pletC $ pcurrentProposalTime # txInfoF.validRange + + let withCurrentTime :: + forall (a :: PType). + Term _ (PCurrentTime :--> a) -> + Term _ a + withCurrentTime f = + pmatch currentTime $ \case + PJust currentTime -> f # currentTime + PNothing -> ptraceError "Unable to resolve current time" + getTimingRelation' <- pletC $ - let currentTime = - passertPJust - # "Current time should be resolved" - #$ currentProposalTime - # txInfoF.validRange - in pgetRelation - # proposalInputDatumF.timingConfig - # proposalInputDatumF.startingTime - # currentTime + withCurrentTime $ + pgetRelation + # proposalInputDatumF.timingConfig + # proposalInputDatumF.startingTime let getTimingRelation = (getTimingRelation' #) . pcon @@ -342,18 +335,23 @@ proposalValidator = resolveStakeInputDatum <- pletC $ presolveStakeInputDatum - # (ptoScottEncoding # sstClass) + # (ptoScottEncodingT # sstClass) # txInfoF.datums + spendStakes' :: Term _ ((PStakeInputsContext :--> PUnit) :--> PUnit) <- pletC $ - plam $ - let stakeInputs = - pmapMaybe - # resolveStakeInputDatum - # pfromData txInfoF.inputs + plam $ \val -> unTermCont $ do + stakeInputs <- + pletC $ + pmapMaybe @PList + # resolveStakeInputDatum + # pfromData txInfoF.inputs - ctx = pcon $ PStakeInputsContext stakeInputs - in (# ctx) + pguardC "Stake inputs not null" $ + pnot #$ pnull # stakeInputs + + let ctx = pcon $ PStakeInputsContext stakeInputs + pure $ val # ctx let spendStakes :: ( PStakeInputsContext _ -> @@ -439,7 +437,7 @@ proposalValidator = stakeF <- pletFieldsC @'["owner", "stakedAmount"] $ ptrace "Exactly one stake input" $ - pfromSingleton # sctxF.inputStakes + ptryFromSingleton # sctxF.inputStakes let newCosigner = stakeF.owner @@ -512,6 +510,12 @@ proposalValidator = pguardC "Proposal time should be wthin the voting period" $ pisWithin # getTimingRelation PVotingPeriod + pguardC "Width of time should meet maximum requirement" $ + withCurrentTime $ + psatisfyMaximumWidth + #$ pfield @"votingTimeRangeMaxWidth" + # proposalInputDatumF.timingConfig + -- Ensure the transaction is voting to a valid 'ResultTag'(outcome). PProposalVotes voteMap <- pmatchC proposalInputDatumF.votes voteFor <- pletC $ pfromData $ pfield @"resultTag" # r @@ -563,40 +567,41 @@ proposalValidator = PUnlockStake _ -> spendStakes $ \sctxF -> do let expectedVotes = - pfoldl - # plam - ( \votes stake -> unTermCont $ do - stakeF <- - pletFieldsC - @'["stakedAmount", "lockedBy"] - stake + pdata $ + pfoldl + # plam + ( \votes stake -> unTermCont $ do + stakeF <- + pletFieldsC + @'["stakedAmount", "lockedBy"] + stake - stakeRoles <- - pletC $ - pgetStakeRoles - # proposalInputDatumF.proposalId - # stakeF.lockedBy + stakeRoles <- + pletC $ + pgetStakeRoles + # proposalInputDatumF.proposalId + # stakeF.lockedBy - pguardC "Stake input should be relevant" $ - pnot #$ pisIrrelevant # stakeRoles + pguardC "Stake input should be relevant" $ + pnot #$ pisIrrelevant # stakeRoles - let canRetractVotes = - pisVoter # stakeRoles + let canRetractVotes = + pisVoter # stakeRoles - voteCount = - pto $ - pfromData stakeF.stakedAmount + voteCount = + pto $ + pfromData stakeF.stakedAmount - newVotes = - pretractVotes - # (pextractVoteOption # stakeRoles) - # voteCount - # votes + newVotes = + pretractVotes + # (pextractVoteOption # stakeRoles) + # voteCount + # votes - pure $ pif canRetractVotes newVotes votes - ) - # proposalInputDatumF.votes - # sctxF.inputStakes + pure $ pif canRetractVotes newVotes votes + ) + # proposalInputDatumF.votes + # sctxF.inputStakes inVotingPeriod = pisWithin # getTimingRelation PVotingPeriod @@ -625,14 +630,19 @@ proposalValidator = .& #thresholds .= proposalInputDatumF.thresholds .& #votes - .= pdata expectedVotes + .= expectedVotes .& #timingConfig .= proposalInputDatumF.timingConfig .& #startingTime .= proposalInputDatumF.startingTime ) - in ptraceIfFalse "Update votes" $ - expectedProposalOut #== proposalOutputDatum + in foldl1 + (#&&) + [ ptraceIfFalse "Votes changed" $ + pnot #$ expectedVotes #== proposalInputDatumF.votes + , ptraceIfFalse "Proposal update correct" $ + expectedProposalOut #== proposalOutputDatum + ] ) -- No change to the proposal is allowed. ( ptraceIfFalse "Proposal unchanged" $ @@ -728,7 +738,7 @@ proposalValidator = . (pfield @"resolved" #) -> value ) -> - psymbolValueOf # gstSymbol # value #== 1 + ptaggedSymbolValueOf # gstSymbol # value #== 1 ) # pfromData txInfoF.inputs diff --git a/agora/Agora/Proposal/Time.hs b/agora/Agora/Proposal/Time.hs index 5fd621b..38b5691 100644 --- a/agora/Agora/Proposal/Time.hs +++ b/agora/Agora/Proposal/Time.hs @@ -22,16 +22,15 @@ module Agora.Proposal.Time ( PPeriod (..), -- * Compute periods given config and starting time. - validateProposalStartingTime, - currentProposalTime, + pvalidateProposalStartingTime, + pcurrentProposalTime, pisProposalTimingConfigValid, pisMaxTimeRangeWidthValid, pgetRelation, pisWithin, + psatisfyMaximumWidth, ) where -import Agora.Utils (pcurrentTimeDuration) -import Control.Composition ((.*)) import Data.Functor ((<&>)) import Plutarch.Api.V1 ( PExtended (PFinite), @@ -46,12 +45,14 @@ import Plutarch.DataRepr ( PDataFields, ) import Plutarch.Extra.Applicative (PApply (pliftA2)) +import Plutarch.Extra.Bool (passert) import Plutarch.Extra.Field (pletAll, pletAllC) import Plutarch.Extra.IsData (PlutusTypeEnumData) import Plutarch.Extra.Maybe (pjust, pmaybe, pnothing) import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pletC, pmatchC) import Plutarch.Extra.Time ( PCurrentTime (PCurrentTime), + pcurrentTimeDuration, pisWithinCurrentTime, ) import Plutarch.Lift ( @@ -59,6 +60,7 @@ import Plutarch.Lift ( PConstantDecl, PUnsafeLiftDecl (PLifted), ) +import Plutarch.Num (PNum) import PlutusLedgerApi.V1 (POSIXTime) import PlutusTx qualified @@ -88,33 +90,6 @@ newtype ProposalStartingTime = ProposalStartingTime PlutusTx.UnsafeFromData ) -{- | Configuration of proposal timings. - - See: https://liqwid.notion.site/Proposals-589853145a994057aa77f397079f75e4#d25ea378768d4c76b52dd4c1b6bc0fcd - - @since 0.1.0 --} -data ProposalTimingConfig = ProposalTimingConfig - { draftTime :: POSIXTime - -- ^ "D": the length of the draft period. - , votingTime :: POSIXTime - -- ^ "V": the length of the voting period. - , lockingTime :: POSIXTime - -- ^ "L": the length of the locking period. - , executingTime :: POSIXTime - -- ^ "E": the length of the execution period. - } - deriving stock - ( -- | @since 0.1.0 - Eq - , -- | @since 0.1.0 - Show - , -- | @since 0.1.0 - Generic - ) - -PlutusTx.makeIsDataIndexed 'ProposalTimingConfig [('ProposalTimingConfig, 0)] - -- | Represents the maximum width of a 'PlutusLedgerApi.V1.Time.POSIXTimeRange'. newtype MaxTimeRangeWidth = MaxTimeRangeWidth {getMaxWidth :: POSIXTime} deriving stock @@ -134,8 +109,41 @@ newtype MaxTimeRangeWidth = MaxTimeRangeWidth {getMaxWidth :: POSIXTime} PlutusTx.FromData , -- | @since 0.1.0 PlutusTx.UnsafeFromData + , -- | @since 1.0.0 + Num ) +{- | Configuration of proposal timings. + + See: https://liqwid.notion.site/Proposals-589853145a994057aa77f397079f75e4#d25ea378768d4c76b52dd4c1b6bc0fcd + + @since 0.1.0 +-} +data ProposalTimingConfig = ProposalTimingConfig + { draftTime :: POSIXTime + -- ^ "D": the length of the draft period. + , votingTime :: POSIXTime + -- ^ "V": the length of the voting period. + , lockingTime :: POSIXTime + -- ^ "L": the length of the locking period. + , executingTime :: POSIXTime + -- ^ "E": the length of the execution period. + , minStakeVotingTime :: POSIXTime + -- ^ Minimum time from creating a voting lock until it can be destroyed. + , votingTimeRangeMaxWidth :: MaxTimeRangeWidth + -- ^ The maximum width of transaction time range while voting. + } + deriving stock + ( -- | @since 0.1.0 + Eq + , -- | @since 0.1.0 + Show + , -- | @since 0.1.0 + Generic + ) + +PlutusTx.makeIsDataIndexed 'ProposalTimingConfig [('ProposalTimingConfig, 0)] + -------------------------------------------------------------------------------- {- | == Establishing timing in Proposal interactions. @@ -210,6 +218,8 @@ newtype PProposalTimingConfig (s :: S) = PProposalTimingConfig , "votingTime" ':= PPOSIXTime , "lockingTime" ':= PPOSIXTime , "executingTime" ':= PPOSIXTime + , "minStakeVotingTime" ':= PPOSIXTime + , "votingTimeRangeMaxWidth" ':= PMaxTimeRangeWidth ] ) } @@ -224,6 +234,8 @@ newtype PProposalTimingConfig (s :: S) = PProposalTimingConfig PIsData , -- | @since 0.1.0 PDataFields + , -- | @since 0.2.1 + PShow ) instance DerivePlutusType PProposalTimingConfig where @@ -260,6 +272,10 @@ newtype PMaxTimeRangeWidth (s :: S) PPartialOrd , -- | @since 0.1.0 POrd + , -- | @since 0.2.1 + PShow + , -- | @since 1.0.0 + PNum ) instance DerivePlutusType PMaxTimeRangeWidth where @@ -303,6 +319,8 @@ pisProposalTimingConfigValid = phoistAcyclic $ , confF.votingTime , confF.lockingTime , confF.executingTime + , confF.minStakeVotingTime + , pto confF.votingTimeRangeMaxWidth ] {- | Return true if the maximum time width is greater than 0. @@ -322,7 +340,7 @@ pisMaxTimeRangeWidthValid = @since 1.0.0 -} -validateProposalStartingTime :: +pvalidateProposalStartingTime :: forall (s :: S). Term s @@ -331,26 +349,23 @@ validateProposalStartingTime :: :--> PProposalStartingTime :--> PBool ) -validateProposalStartingTime = phoistAcyclic $ - plam $ \(pto -> maxDuration) iv (pto -> st) -> +pvalidateProposalStartingTime = phoistAcyclic $ + plam $ \maxWidth iv (pto -> st) -> pmaybe - # ptrace - "validateProposalStartingTime: unable to get current time" - (pconstant False) + # pconstant False # plam ( \ct -> - let duration = pcurrentTimeDuration # ct - isTightEnough = + let isTightEnough = ptraceIfFalse "createProposalStartingTime: given time range should be tight enough" - $ duration #<= maxDuration + $ psatisfyMaximumWidth # maxWidth # ct isInCurrentTimeRange = ptraceIfFalse "createProposalStartingTime: starting time should be in current time range" $ pisWithinCurrentTime # st # ct in isTightEnough #&& isInCurrentTimeRange ) - # (currentProposalTime # iv) + # (pcurrentProposalTime # iv) {- | Get the current proposal time, given the 'PlutusLedgerApi.V1.txInfoValidPeriod' field. @@ -364,8 +379,8 @@ validateProposalStartingTime = phoistAcyclic $ @since 0.1.0 -} -currentProposalTime :: forall (s :: S). Term s (PPOSIXTimeRange :--> PMaybe PProposalTime) -currentProposalTime = phoistAcyclic $ +pcurrentProposalTime :: forall (s :: S). Term s (PPOSIXTimeRange :--> PMaybe PProposalTime) +pcurrentProposalTime = phoistAcyclic $ plam $ \iv -> unTermCont $ do PInterval iv' <- pmatchC iv ivf <- pletAllC iv' @@ -386,7 +401,13 @@ currentProposalTime = phoistAcyclic $ PFinite (pfromData . (pfield @"_0" #) -> d) -> pjust # d _ -> ptrace "currentProposalTime: time range should be bounded" pnothing - mkTime = phoistAcyclic $ plam $ pcon .* PCurrentTime + mkTime = phoistAcyclic $ + plam $ \lb ub -> + passert + "Upper bound bigger than lower bound" + (lb #< ub) + (pcon $ PCurrentTime lb ub) + pure $ pliftA2 # mkTime # lowerBound # upperBound {- | Represent relation between current time and a given period. @@ -494,3 +515,22 @@ pgetRelation = phoistAcyclic $ pif (plb #<= lb #&& ub #<= pub) (pcon PWithin) $ pif (pub #< lb) (pcon PAfter) $ ptraceError "pgetRelation: too early or invalid current time" + +{- | Return true if the width of given 'PProposalTime' is shorter than the + maximum. + + @since 1.0.0 +-} +psatisfyMaximumWidth :: + forall (s :: S). + Term + s + ( PMaxTimeRangeWidth + :--> PProposalTime + :--> PBool + ) +psatisfyMaximumWidth = phoistAcyclic $ + plam $ \maxWidth time -> + let width = pcurrentTimeDuration # time + max = pto maxWidth + in width #<= max diff --git a/agora/Agora/Stake.hs b/agora/Agora/Stake.hs index 671f1f9..df2e3f7 100644 --- a/agora/Agora/Stake.hs +++ b/agora/Agora/Stake.hs @@ -12,11 +12,13 @@ module Agora.Stake ( -- * Haskell-land StakeDatum (..), StakeRedeemer (..), + ProposalAction (..), ProposalLock (..), -- * Plutarch-land PStakeDatum (..), PStakeRedeemer (..), + PProposalAction (..), PProposalLock (..), PStakeRole (..), @@ -42,18 +44,18 @@ module Agora.Stake ( ) where import Agora.Proposal ( + PProposalDatum, PProposalId, PProposalRedeemer, - PProposalStatus, PResultTag, ProposalId, ResultTag, ) -import Agora.SafeMoney (GTTag) -import Agora.Utils (pmapMaybe, ppureIf) +import Agora.Proposal.Time (PProposalTime) +import Agora.SafeMoney (GTTag, StakeSTTag) import Data.Tagged (Tagged) import Generics.SOP qualified as SOP -import Plutarch.Api.V1 (PCredential) +import Plutarch.Api.V1 (PCredential, PPOSIXTime) import Plutarch.Api.V2 ( KeyGuarantees (Unsorted), PDatum, @@ -67,26 +69,62 @@ import Plutarch.DataRepr ( DerivePConstantViaData (DerivePConstantViaData), PDataFields, ) +import Plutarch.Extra.Applicative (ppureIf) import Plutarch.Extra.AssetClass (PAssetClass) -import Plutarch.Extra.Field (pletAll) import Plutarch.Extra.IsData ( DerivePConstantViaDataList (DerivePConstantViaDataList), ProductIsData (ProductIsData), ) -import "liqwid-plutarch-extra" Plutarch.Extra.List (pfindJust) +import "liqwid-plutarch-extra" Plutarch.Extra.List (pfindJust, pmapMaybe) import Plutarch.Extra.Maybe (passertPJust, pjust, pnothing) -import Plutarch.Extra.ScriptContext (pfromOutputDatum) +import Plutarch.Extra.ScriptContext (ptryFromOutputDatum) import Plutarch.Extra.Sum (PSum (PSum)) import Plutarch.Extra.Tagged (PTagged) import Plutarch.Extra.Traversable (pfoldMap) -import Plutarch.Extra.Value (passetClassValueOf) +import Plutarch.Extra.Value (passetClassValueOfT) import Plutarch.Lift (PConstantDecl, PUnsafeLiftDecl (PLifted)) -import Plutarch.Orphans () -import PlutusLedgerApi.V2 (Credential) +import PlutusLedgerApi.V2 (Credential, POSIXTime) import PlutusTx qualified -------------------------------------------------------------------------------- +{- | The action that was performed on a particular proposal. + + @since 1.0.0 +-} +data ProposalAction + = -- | The stake was used to create a proposal. + -- + -- This kind of lock is placed upon the creation of a proposal, in order + -- to limit creation of proposals per stake. + -- + -- See also: https://github.com/Liqwid-Labs/agora/issues/68 + Created + | -- | The stake was used to vote on a proposal. + -- + -- This kind of lock is placed while voting on a proposal, in order to + -- prevent depositing and withdrawing when votes are in place. + Voted + ResultTag + -- ^ The option which was voted on. This allows votes to be retracted. + POSIXTime + -- ^ The upper bound of the transaction time range when the lock is created. + | -- | The stake was used to cosign a proposal.` + Cosigned + deriving stock + ( -- | @since 1.0.0 + Show + , -- | @since 1.0.0 + Generic + ) + +PlutusTx.makeIsDataIndexed + ''ProposalAction + [ ('Created, 0) + , ('Voted, 1) + , ('Cosigned, 2) + ] + {- | Locks that are stored in the stake datums for various purposes. NOTE: Due to retracting votes always being possible, @@ -112,45 +150,31 @@ import PlutusTx qualified └──────────────┘ └─────────────────┘ @ - @since 0.1.0 + @since 1.0.0 -} -data ProposalLock - = -- | The stake was used to create a proposal. - -- - -- This kind of lock is placed upon the creation of a proposal, in order - -- to limit creation of proposals per stake. - -- - -- See also: https://github.com/Liqwid-Labs/agora/issues/68 - -- - -- @since 0.2.0 - Created - ProposalId - -- ^ The identifier of the proposal. - | -- | The stake was used to vote on a proposal. - -- - -- This kind of lock is placed while voting on a proposal, in order to - -- prevent depositing and withdrawing when votes are in place. - -- - -- @since 0.2.0 - Voted - ProposalId - -- ^ The identifier of the proposal. - ResultTag - -- ^ The option which was voted on. This allows votes to be retracted. - | Cosigned ProposalId +data ProposalLock = ProposalLock + { proposalId :: ProposalId + -- ^ The identifier of the proposal. + , action :: ProposalAction + -- ^ The action that has been performed. + } deriving stock ( -- | @since 0.1.0 Show , -- | @since 0.1.0 Generic ) - -PlutusTx.makeIsDataIndexed - ''ProposalLock - [ ('Created, 0) - , ('Voted, 1) - , ('Cosigned, 2) - ] + deriving anyclass + ( -- | @since 0.1.0 + SOP.Generic + ) + deriving + ( -- | @since 0.1.0 + PlutusTx.ToData + , -- | @since 0.1.0 + PlutusTx.FromData + ) + via (ProductIsData ProposalLock) {- | Haskell-level redeemer for Stake scripts. @@ -160,7 +184,7 @@ data StakeRedeemer = -- | Deposit or withdraw a discrete amount of the staked governance token. -- Stake must be unlocked. DepositWithdraw (Tagged GTTag Integer) - | -- | Destroy a stake, retrieving its LQ, the minimum ADA and any other assets. + | -- | Destroy a stake, retrieving its GT, the minimum ADA and any other assets. -- Stake must be unlocked. Destroy | -- | Permit a Vote to be added onto a 'Agora.Proposal.Proposal'. @@ -268,6 +292,7 @@ newtype PStakeDatum (s :: S) = PStakeDatum PShow ) +-- | @since 1.0.0 instance DerivePlutusType PStakeDatum where type DPTStrat _ = PlutusTypeNewtype @@ -291,7 +316,7 @@ instance PTryFrom PData (PAsData PStakeDatum) data PStakeRedeemer (s :: S) = -- | Deposit or withdraw a discrete amount of the staked governance token. PDepositWithdraw (Term s (PDataRecord '["delta" ':= PTagged GTTag PInteger])) - | -- | Destroy a stake, retrieving its LQ, the minimum ADA and any other assets. + | -- | Destroy a stake, retrieving its GT, the minimum ADA and any other assets. PDestroy (Term s (PDataRecord '[])) | PPermitVote (Term s (PDataRecord '[])) | PRetractVotes (Term s (PDataRecord '[])) @@ -325,32 +350,65 @@ deriving via instance (PConstantDecl StakeRedeemer) -{- | Plutarch-level version of 'ProposalLock'. +{- | Plutarch-level version of 'ProposalAction'. - @since 0.2.0 + @since 1.0.0 -} -data PProposalLock (s :: S) - = PCreated - ( Term - s - ( PDataRecord - '["created" ':= PProposalId] - ) - ) +data PProposalAction (s :: S) + = PCreated (Term s (PDataRecord '[])) | PVoted ( Term s ( PDataRecord - '[ "votedOn" ':= PProposalId - , "votedFor" ':= PResultTag + '[ "votedFor" ':= PResultTag + , "createdAt" ':= PPOSIXTime ] ) ) - | PCosigned + | PCosigned (Term s (PDataRecord '[])) + deriving stock + ( -- | @since 1.0.0 + Generic + ) + deriving anyclass + ( -- | @since 1.0.0 + PlutusType + , -- | @since 1.0.0 + PIsData + , -- | @since 1.0.0 + PEq + , -- | @since 1.0.0 + PShow + ) + +-- | @since 1.0.0 +instance DerivePlutusType PProposalAction where + type DPTStrat _ = PlutusTypeData + +-- | @since 1.0.0 +instance PUnsafeLiftDecl PProposalAction where + type PLifted _ = ProposalAction + +-- | @since 1.0.0 +deriving via + (DerivePConstantViaData ProposalAction PProposalAction) + instance + (PConstantDecl ProposalAction) + +-- | @since 1.0.0 +instance PTryFrom PData PProposalAction + +{- | Plutarch-level version of 'ProposalLock'. + + @since 1.0.0 +-} +newtype PProposalLock (s :: S) + = PProposalLock ( Term s ( PDataRecord - '[ "cosigned" ':= PProposalId + '[ "proposalId" ':= PProposalId + , "action" ':= PProposalAction ] ) ) @@ -365,15 +423,15 @@ data PProposalLock (s :: S) PIsData , -- | @since 0.1.0 PEq + , -- | @since 1.0.0 + PDataFields , -- | @since 0.2.0 PShow ) +-- | @since 0.2.0 instance DerivePlutusType PProposalLock where - type DPTStrat _ = PlutusTypeData - --- | @since 0.1.0 -instance PTryFrom PData PProposalLock + type DPTStrat _ = PlutusTypeNewtype -- | @since 0.2.0 instance PTryFrom PData (PAsData PProposalLock) @@ -384,7 +442,7 @@ instance PUnsafeLiftDecl PProposalLock where -- | @since 0.1.0 deriving via - (DerivePConstantViaData ProposalLock PProposalLock) + (DerivePConstantViaDataList ProposalLock PProposalLock) instance (PConstantDecl ProposalLock) @@ -412,9 +470,11 @@ pnumCreatedProposals = pto $ pfoldMap # plam - ( \(pfromData -> lock) -> pmatch lock $ \case - PCreated _ -> pcon $ PSum 1 - _ -> mempty + ( \lock -> + let action = pfromData $ pfield @"action" # lock + in pmatch action $ \case + PCreated _ -> pcon $ PSum 1 + _ -> mempty ) # l @@ -525,9 +585,9 @@ instance DerivePlutusType PStakeRedeemerContext where data PProposalContext (s :: S) = -- | A proposal is spent. PSpendProposal - (Term s PProposalId) - (Term s PProposalStatus) + (Term s PProposalDatum) (Term s PProposalRedeemer) + (Term s PProposalTime) | -- | A new proposal is created. PNewProposal (Term s PProposalId) @@ -665,26 +725,17 @@ pgetStakeRoles :: ) pgetStakeRoles = phoistAcyclic $ plam $ \pid -> - pmapMaybe - # plam - ( flip - pmatch - ( \case - PCreated ((pfield @"created" #) -> pid') -> - ppureIf - # (pid' #== pid) - # pcon PCreator - PVoted r -> pletAll r $ \rF -> - ppureIf - # (rF.votedOn #== pid) - # pcon (PVoter rF.votedFor) - PCosigned ((pfield @"cosigned" #) -> pid') -> - ppureIf - # (pid' #== pid) - # pcon PCosigner - ) - . pfromData - ) + let getStakeRole = flip (pletFields @'["proposalId", "action"]) $ + \lockF -> + ppureIf + # (pid #== lockF.proposalId) + #$ pmatch lockF.action + $ \case + PCreated _ -> pcon PCreator + PVoted ((pfield @"votedFor" #) -> tag) -> + pcon $ PVoter tag + PCosigned _ -> pcon PCosigner + in pmapMaybe # plam (getStakeRole . pfromData) {- | Get the outcome that was voted for. @@ -715,7 +766,7 @@ presolveStakeInputDatum :: forall (s :: S). Term s - ( PAssetClass + ( PTagged StakeSTTag PAssetClass :--> PMap 'Unsorted PDatumHash PDatum :--> PTxInInfo :--> PMaybe PStakeDatum @@ -726,7 +777,7 @@ presolveStakeInputDatum = phoistAcyclic $ (pletFields @'["value", "datum", "address"]) ( \txOutF -> let isStakeUTxO = - passetClassValueOf + passetClassValueOfT # sstClass # txOutF.value #== 1 @@ -734,7 +785,7 @@ presolveStakeInputDatum = phoistAcyclic $ datum = ptrace "Resolve stake datum" $ pfromData $ - pfromOutputDatum @(PAsData PStakeDatum) + ptryFromOutputDatum @(PAsData PStakeDatum) # txOutF.datum # datums in pif diff --git a/agora/Agora/Stake/Redeemers.hs b/agora/Agora/Stake/Redeemers.hs index e829221..8ae229d 100644 --- a/agora/Agora/Stake/Redeemers.hs +++ b/agora/Agora/Stake/Redeemers.hs @@ -19,13 +19,15 @@ import Agora.Proposal ( PProposalRedeemer (PCosign, PUnlockStake, PVote), ProposalStatus (Finished), ) +import Agora.Proposal.Time (PProposalTime) import Agora.Stake ( + PProposalAction (PCosigned, PCreated, PVoted), PProposalContext ( PNewProposal, PNoProposal, PSpendProposal ), - PProposalLock (PCosigned, PCreated, PVoted), + PProposalLock (PProposalLock), PSigContext (owner, signedBy), PSignedBy ( PSignedByDelegate, @@ -48,13 +50,20 @@ import Agora.Stake ( ), pstakeLocked, ) -import Agora.Utils (pfromSingleton, pisSingleton, pmustDeleteBy) +import Data.Functor ((<&>)) import Plutarch.Api.V1.Address (PCredential) -import Plutarch.Api.V2 (PMaybeData) +import Plutarch.Api.V2 (PMaybeData, PPOSIXTime) +import Plutarch.Extra.Bool (passert) import Plutarch.Extra.Field (pletAll, pletAllC) -import Plutarch.Extra.Maybe (pdjust, pdnothing, pmaybeData) +import "liqwid-plutarch-extra" Plutarch.Extra.List ( + pisSingleton, + ptryDeleteFirstBy, + ptryFromSingleton, + ) +import Plutarch.Extra.Maybe (pdjust, pdnothing, pjust, pmaybe, pmaybeData, pnothing) import Plutarch.Extra.Record (mkRecordConstr, (.&), (.=)) -import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pguardC, pletC, pmatchC) +import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pguardC, pletC, pletFieldsC, pmatchC) +import Plutarch.Extra.Time (PCurrentTime (PCurrentTime)) -- | A wrapper which ensures that no proposal is presented in the transaction. pwithoutProposal :: @@ -87,7 +96,7 @@ pbatchUpdateInputs = phoistAcyclic $ plam $ \f -> flip pmatch $ \ctxF -> pnull #$ pfoldr - # (pmustDeleteBy # f) + # plam (\x -> ptryDeleteFirstBy # (f # x)) # ctxF.stakeOutputDatums # ctxF.stakeInputDatums @@ -159,17 +168,13 @@ pvoteHelper :: :--> PStakeRedeemerHandler ) pvoteHelper = phoistAcyclic $ - plam $ \valProposalCtx ctx -> unTermCont $ do - pguardC "Owner or delegate signs this transaction" $ - pisSignedBy # pconstant True # ctx - + plam $ \valProposalCtx ctx -> -- This puts trust into the Proposal. The Proposal must necessarily check -- that this is not abused. - - pguardC "Correct outputs" $ - ponlyLocksUpdated # (valProposalCtx # ctx) # ctx - - pure $ pconstant () + passert + "Correct outputs" + (ponlyLocksUpdated # (valProposalCtx # ctx) # ctx) + (pconstant ()) -- | Add new lock the the existing list of locked. paddNewLock :: @@ -199,33 +204,60 @@ ppermitVote = pvoteHelper #$ phoistAcyclic $ pguardC "Only one stake input allowed" $ pisSingleton # ctxF.stakeInputDatums + pguardC "Owner signs this transaction" $ + pisSignedBy # pconstant False # ctx + pure lock pure $ paddNewLock #$ pmatch ctxF.proposalContext $ \case - PSpendProposal pid _ r -> pmatch r $ \case - PVote ((pfromData . (pfield @"resultTag" #)) -> voteFor) -> - mkRecordConstr - PVoted - ( #votedOn - .= pdata pid - .& #votedFor - .= pdata voteFor - ) - PCosign _ -> - withOnlyOneStakeInput - #$ mkRecordConstr - PCosigned - ( #cosigned .= pdata pid + PSpendProposal proposal redeemer currentTime -> unTermCont $ do + mkLock <- pletC $ + plam $ \action -> + mkRecordConstr + PProposalLock + ( #proposalId + .= pfield @"proposalId" + # proposal + .& #action + .= pdata action ) - _ -> ptraceError "Expected Vote" - PNewProposal pid -> - withOnlyOneStakeInput - #$ mkRecordConstr - PCreated - ( #created .= pdata pid - ) - _ -> ptraceError "Expected proposal" + + pure $ + pmatch redeemer $ \case + PVote ((pfromData . (pfield @"resultTag" #)) -> voteFor) -> + unTermCont $ do + pguardC "Owner or delegatee signs the transaction" $ + pisSignedBy # pconstant True # ctx + + PCurrentTime _ upperBound <- pmatchC currentTime + + let action = + mkRecordConstr + PVoted + ( #votedFor + .= pdata voteFor + .& #createdAt + .= pdata upperBound + ) + + pure $ mkLock # action + PCosign _ -> + let action = pcon $ PCosigned pdnil + in withOnlyOneStakeInput #$ mkLock # action + _ -> ptraceError "Expected Vote or Cosign" + PNewProposal proposalId -> + let action = pcon $ PCreated pdnil + lock = + mkRecordConstr + PProposalLock + ( #proposalId + .= pdata proposalId + .& #action + .= pdata action + ) + in withOnlyOneStakeInput # lock + _ -> ptraceError "Expected a proposal to be spent or created" data PRemoveLocksMode (s :: S) = PRemoveVoterLockOnly | PRemoveAllLocks deriving stock (Generic) @@ -235,33 +267,59 @@ instance DerivePlutusType PRemoveLocksMode where type DPTStrat _ = PlutusTypeScott {- | Remove stake locks with the proposal id given the list of existing locks. - The first parameter controls whether to revmove creator locks or not. + The first parameter controls whether to remove creator locks or not. If + one of the locks performed voting action, the unlock cooldown will be + checked if it's given. -} premoveLocks :: forall (s :: S). Term s ( PProposalId + :--> PMaybe PPOSIXTime + :--> PProposalTime :--> PRemoveLocksMode :--> PBuiltinList (PAsData PProposalLock) :--> PBuiltinList (PAsData PProposalLock) ) -premoveLocks = phoistAcyclic $ - plam $ \pid rl -> unTermCont $ do - shouldRemoveOtherLocks <- pletC $ - plam $ \pid' -> - pid' #== pid #&& rl #== pcon PRemoveAllLocks +premoveLocks = + phoistAcyclic $ + plam $ \proposalId unlockCooldown currentTime mode -> unTermCont $ do + shouldRemoveAllLocks <- pletC $ mode #== pcon PRemoveAllLocks - pure $ - pfilter - # plam - ( \(pfromData -> l) -> pnot #$ pmatch l $ \case - PCosigned ((pfield @"cosigned" #) -> pid') -> - shouldRemoveOtherLocks # pid' - PCreated ((pfield @"created" #) -> pid') -> - shouldRemoveOtherLocks # pid' - PVoted ((pfield @"votedOn" #) -> pid') -> pid' #== pid - ) + PCurrentTime lowerBound _ <- pmatchC currentTime + + let handleVoter + ( (pfield @"createdAt" #) -> + createdAt + ) = + let notInCooldown = + pmaybe + # pconstant True + # plam (\c -> createdAt + c #<= lowerBound) + # unlockCooldown + in foldl1 + (#||) + [ shouldRemoveAllLocks + , ptraceIfFalse "Stake lock in cooldown" notInCooldown + ] + + handleLock = + plam $ + flip + pletAll + ( \lockF -> + foldl1 + (#&&) + [ proposalId #== lockF.proposalId + , pmatch lockF.action $ \case + PVoted r -> handleVoter r + _ -> shouldRemoveAllLocks + ] + ) + . pfromData + + pure $ pfilter # handleLock {- | Default implementation of 'Agora.Stake.RetractVotes'. @@ -269,17 +327,41 @@ premoveLocks = phoistAcyclic $ -} pretractVote :: forall (s :: S). Term s PStakeRedeemerHandler pretractVote = pvoteHelper #$ phoistAcyclic $ - plam $ - flip pmatch $ \ctxF -> + plam $ \ctx -> + pmatch ctx $ \ctxF -> pmatch ctxF.proposalContext $ \case - PSpendProposal pid s r -> pmatch r $ \case - PUnlockStake _ -> - let mode = - pif - (s #== pconstant Finished) - (pcon PRemoveAllLocks) - (pcon PRemoveVoterLockOnly) - in premoveLocks # pid # mode + PSpendProposal proposal redeemer currentTime -> pmatch redeemer $ \case + PUnlockStake _ -> unTermCont $ do + proposalF <- + pletFieldsC + @'[ "proposalId" + , "status" + , "timingConfig" + ] + proposal + + (mode, unlockCooldown) <- + pmatchC (proposalF.status #== pconstant Finished) <&> \case + PTrue -> + ( pcon PRemoveAllLocks + , pnothing + ) + _ -> + ( pcon PRemoveVoterLockOnly + , pjust + #$ pfield @"minStakeVotingTime" + # proposalF.timingConfig + ) + + pguardC "Authorized by either opwner or delegatee" $ + pisSignedBy # pconstant True # ctx + + pure $ + premoveLocks + # proposalF.proposalId + # unlockCooldown + # currentTime + # mode _ -> ptraceError "Expected unlock" _ -> ptraceError "Expected spending proposal" @@ -387,12 +469,12 @@ pdepositWithdraw = phoistAcyclic $ stakeInputDatum <- pletC $ ptrace "Single stake input" $ - pfromSingleton # ctxF.stakeInputDatums + ptryFromSingleton # ctxF.stakeInputDatums stakeInputDatumF <- pletAllC stakeInputDatum let stakeOutputDatum = ptrace "Single stake output" $ - pfromSingleton # ctxF.stakeOutputDatums + ptryFromSingleton # ctxF.stakeOutputDatums ---------------------------------------------------------------------------- diff --git a/agora/Agora/Stake/Scripts.hs b/agora/Agora/Stake/Scripts.hs index c3ab8bf..aaa6582 100644 --- a/agora/Agora/Stake/Scripts.hs +++ b/agora/Agora/Stake/Scripts.hs @@ -13,6 +13,8 @@ module Agora.Stake.Scripts ( import Agora.Credential (authorizationContext, pauthorizedBy) import Agora.Proposal (PProposalDatum, PProposalRedeemer) +import Agora.Proposal.Time (pcurrentProposalTime) +import Agora.SafeMoney (GTTag, ProposalSTTag, StakeSTTag) import Agora.Stake ( PProposalContext ( PNewProposal, @@ -52,13 +54,7 @@ import Agora.Stake.Redeemers ( ppermitVote, pretractVote, ) -import Agora.Utils ( - passert, - pisDNothing, - pmapMaybe, - psymbolValueOf', - pvalidatorHashToTokenName, - ) +import Agora.Utils (pisDNothing, ptoScottEncodingT, puntag) import Plutarch.Api.V1 ( PCredential (PPubKeyCredential, PScriptCredential), PCurrencySymbol, @@ -77,13 +73,14 @@ import Plutarch.Extra.AssetClass ( PAssetClass, PAssetClassData, passetClass, - ptoScottEncoding, ) +import Plutarch.Extra.Bool (passert) import Plutarch.Extra.Field (pletAll, pletAllC) import Plutarch.Extra.Functor (PFunctor (pfmap)) -import "liqwid-plutarch-extra" Plutarch.Extra.List (pfindJust) +import "liqwid-plutarch-extra" Plutarch.Extra.List (pfindJust, pmapMaybe) import Plutarch.Extra.Maybe ( passertPJust, + pdjust, pfromJust, pfromMaybe, pjust, @@ -93,9 +90,12 @@ import Plutarch.Extra.Maybe ( import Plutarch.Extra.Ord (POrdering (PEQ, PGT, PLT), pcompareBy, pfromOrd) import Plutarch.Extra.ScriptContext ( pfindTxInByTxOutRef, - pfromOutputDatum, + ptryFromOutputDatum, + pvalidatorHashFromAddress, + pvalidatorHashToTokenName, pvalueSpent, ) +import Plutarch.Extra.Tagged (PTagged) import "liqwid-plutarch-extra" Plutarch.Extra.TermCont ( pguardC, pletC, @@ -105,7 +105,9 @@ import "liqwid-plutarch-extra" Plutarch.Extra.TermCont ( ) import Plutarch.Extra.Value ( passetClassValueOf, + passetClassValueOfT, psymbolValueOf, + psymbolValueOf', ) import Plutarch.Num (PNum (pnegate)) import Plutarch.Unsafe (punsafeCoerce) @@ -131,15 +133,14 @@ import Prelude hiding (Num ((+))) == Arguments Following arguments should be provided(in this order): - 1. governor ST assetclass + 1. governance token assetclass @since 1.0.0 -} stakePolicy :: - -- | The (governance) token that a Stake can store. - ClosedTerm (PAssetClassData :--> PMintingPolicy) + ClosedTerm (PTagged GTTag PAssetClassData :--> PMintingPolicy) stakePolicy = - plam $ \gstClass _redeemer ctx' -> unTermCont $ do + plam $ \gtClass _redeemer ctx' -> unTermCont $ do ctx <- pletFieldsC @'["txInfo", "purpose"] ctx' txInfo <- pletC $ ctx.txInfo let _a :: Term _ PTxInfo @@ -197,7 +198,7 @@ stakePolicy = datumF <- pletAllC $ pfromData $ - pfromOutputDatum @(PAsData PStakeDatum) + ptryFromOutputDatum @(PAsData PStakeDatum) # outputF.datum # txInfoF.datums @@ -205,10 +206,10 @@ stakePolicy = foldl1 (#&&) [ ptraceIfFalse "Stake ouput has expected amount of stake token" $ - passetClassValueOf - # (ptoScottEncoding # gstClass) + passetClassValueOfT + # (ptoScottEncodingT # gtClass) # outputF.value - #== pto (pfromData datumF.stakedAmount) + #== pfromData datumF.stakedAmount , ptraceIfFalse "Stake Owner should sign the transaction" $ pauthorizedBy # authorizationContext txInfoF @@ -232,17 +233,17 @@ stakePolicy = Following arguments should be provided(in this order): 1. stake ST symbol 2. proposal ST assetclass - 3. governor ST assetclass + 3. governance token assetclass @since 1.0.0 -} mkStakeValidator :: StakeRedeemerImpl s -> - Term s PCurrencySymbol -> - Term s PAssetClass -> - Term s PAssetClass -> + Term s (PTagged StakeSTTag PCurrencySymbol) -> + Term s (PTagged ProposalSTTag PAssetClass) -> + Term s (PTagged GTTag PAssetClass) -> Term s PValidator -mkStakeValidator impl sstSymbol pstClass gstClass = +mkStakeValidator impl sstSymbol pstClass gtClass = plam $ \_datum redeemer ctx -> unTermCont $ do ctxF <- pletFieldsC @'["txInfo", "purpose"] ctx txInfo <- pletC $ pfromData ctxF.txInfo @@ -256,6 +257,7 @@ mkStakeValidator impl sstSymbol pstClass gstClass = , "signatories" , "redeemers" , "datums" + , "validRange" ] txInfo @@ -271,18 +273,16 @@ mkStakeValidator impl sstSymbol pstClass gstClass = # (pfield @"_0" # stakeInputRef) # txInfoF.inputs - stakeValidatorCredential <- + stakeValidatorHash <- pletC $ - pfield @"credential" + pfromJust + #$ pvalidatorHashFromAddress #$ pfield @"address" # validatedInput - let sstName = pvalidatorHashToTokenName #$ pmatch stakeValidatorCredential $ - \case - PScriptCredential r -> pfield @"_0" # r - _ -> perror + let sstName = pvalidatorHashToTokenName stakeValidatorHash - sstClass <- pletC $ passetClass # sstSymbol # sstName + sstClass <- pletC $ passetClass # puntag sstSymbol # sstName -------------------------------------------------------------------------- @@ -302,15 +302,18 @@ mkStakeValidator impl sstSymbol pstClass gstClass = PGT -> ptraceError "More than one SST in one UTxO" -- 1 PEQ -> - let ownerCredential = pfield @"credential" # txOutF.address + let ownerValidatoHash = + pfromJust + #$ pvalidatorHashFromAddress + # txOutF.address isOwnedByStakeValidator = - ownerCredential #== stakeValidatorCredential + ownerValidatoHash #== stakeValidatorHash datum = ptrace "Resolve stake datum" $ pfromData $ - pfromOutputDatum @(PAsData PStakeDatum) + ptryFromOutputDatum @(PAsData PStakeDatum) # txOutF.datum # txInfoF.datums in passert @@ -342,7 +345,7 @@ mkStakeValidator impl sstSymbol pstClass gstClass = authorizedBy <- pletC $ pauthorizedBy # authorizationContext txInfoF - PPair allHaveSameOwner allHaveSameDelegatee <- + PPair allHaveSameOwner allHaveSameOrOwnedByDelegatee <- pmatchC $ pfoldr # plam @@ -355,11 +358,15 @@ mkStakeValidator impl sstSymbol pstClass gstClass = allHaveSameOwner #&& dF.owner #== firstStakeInputDatumF.owner - allHaveSameDelegatee' = - allHaveSameDelegatee - #&& dF.delegatedTo - #== firstStakeInputDatumF.delegatedTo - in pcon $ PPair allHaveSameOwner' allHaveSameDelegatee' + allHaveSameOrOwnedByDelegatee' = + let delegated = + dF.delegatedTo #== firstStakeInputDatumF.delegatedTo + ownedByDelegatee = + pdata (pdjust # dF.owner) + #== firstStakeInputDatumF.delegatedTo + in allHaveSameDelegatee + #&& (delegated #|| ownedByDelegatee) + in pcon $ PPair allHaveSameOwner' allHaveSameOrOwnedByDelegatee' ) # pcon (PPair (pconstant True) (pconstant True)) # restOfStakeInputDatums @@ -370,7 +377,7 @@ mkStakeValidator impl sstSymbol pstClass gstClass = # firstStakeInputDatumF.owner delegateSignsTransaction = - allHaveSameDelegatee + allHaveSameOrOwnedByDelegatee #&& pmaybeData # pconstant False # plam ((authorizedBy #) . pfromData) @@ -407,13 +414,12 @@ mkStakeValidator impl sstSymbol pstClass gstClass = ( \output -> let validateGT = plam $ \stakeDatum -> let expected = - pto $ - pfromData $ - pfield @"stakedAmount" # stakeDatum + pfromData $ + pfield @"stakedAmount" # stakeDatum actual = - passetClassValueOf - # gstClass + passetClassValueOfT + # gtClass # (pfield @"value" # output) in pif (expected #== actual) @@ -433,19 +439,20 @@ mkStakeValidator impl sstSymbol pstClass gstClass = plam $ flip pletAll $ \txOutF -> let isProposalUTxO = - passetClassValueOf + passetClassValueOfT # pstClass # txOutF.value #== 1 + proposalDatum = pfromData $ - pfromOutputDatum @(PAsData PProposalDatum) + ptryFromOutputDatum @(PAsData PProposalDatum) # txOutF.datum # txInfoF.datums in pif isProposalUTxO (pjust # proposalDatum) pnothing let pstMinted = - passetClassValueOf # pstClass # txInfoF.mint #== 1 + passetClassValueOfT # pstClass # txInfoF.mint #== 1 newProposalContext = pcon $ @@ -477,10 +484,13 @@ mkStakeValidator impl sstSymbol pstClass gstClass = pfmap # plam ( \proposalDatum -> - let id = pfield @"proposalId" # proposalDatum - status = pfield @"status" # proposalDatum - redeemer = getProposalRedeemer # inInfoF.outRef - in pcon $ PSpendProposal id status redeemer + let redeemer = getProposalRedeemer # inInfoF.outRef + currentTime = + passertPJust + # "Should resolve proposal time" + #$ pcurrentProposalTime + # txInfoF.validRange + in pcon $ PSpendProposal proposalDatum redeemer currentTime ) #$ getProposalDatum # pfromData inInfoF.resolved @@ -598,15 +608,15 @@ mkStakeValidator impl sstSymbol pstClass gstClass = Following arguments should be provided(in this order): 1. stake ST symbol 2. proposal ST assetclass - 3. governor ST assetclass + 3. governance token assetclass @since 1.0.0 -} stakeValidator :: ClosedTerm - ( PCurrencySymbol - :--> PAssetClassData - :--> PAssetClassData + ( PTagged StakeSTTag PCurrencySymbol + :--> PTagged ProposalSTTag PAssetClassData + :--> PTagged GTTag PAssetClassData :--> PValidator ) stakeValidator = @@ -622,5 +632,5 @@ stakeValidator = } ) sstSymbol - (ptoScottEncoding # pstClass) - (ptoScottEncoding # gstClass) + (ptoScottEncodingT # pstClass) + (ptoScottEncodingT # gstClass) diff --git a/agora/Agora/Treasury.hs b/agora/Agora/Treasury.hs index 77ac360..a48793e 100644 --- a/agora/Agora/Treasury.hs +++ b/agora/Agora/Treasury.hs @@ -13,8 +13,10 @@ module Agora.Treasury ( ) where import Agora.AuthorityToken (singleAuthorityTokenBurned) +import Agora.SafeMoney (AuthorityTokenTag) import Plutarch.Api.V1.Value (PCurrencySymbol, PValue) import Plutarch.Api.V2 (PScriptPurpose (PSpending), PValidator) +import Plutarch.Extra.Tagged (PTagged) import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pguardC, pletFieldsC, pmatchC) {- | Validator ensuring that transactions consuming the treasury @@ -25,10 +27,10 @@ import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pguardC, pletFieldsC, pm Following arguments should be provided(in this order): 1. authority token symbol - @since 0.1.0 + @since 1.0.0 -} treasuryValidator :: - ClosedTerm (PCurrencySymbol :--> PValidator) + ClosedTerm (PTagged AuthorityTokenTag PCurrencySymbol :--> PValidator) treasuryValidator = plam $ \atSymbol _ _ ctx' -> unTermCont $ do -- plet required fields from script context. ctx <- pletFieldsC @["txInfo", "purpose"] ctx' diff --git a/agora/Agora/Utils.hs b/agora/Agora/Utils.hs index 8288ea1..c589ed5 100644 --- a/agora/Agora/Utils.hs +++ b/agora/Agora/Utils.hs @@ -8,101 +8,34 @@ Description: Plutarch utility functions that should be upstreamed or don't belon Plutarch utility functions that should be upstreamed or don't belong anywhere else. -} module Agora.Utils ( - validatorHashToTokenName, validatorHashToAddress, - pltAsData, - withBuiltinPairAsData, - pvalidatorHashToTokenName, - pscriptHashToTokenName, - scriptHashToTokenName, - plistEqualsBy, pstringIntercalate, punwords, - pcurrentTimeDuration, - pdelete, - pdeleteBy, - pmustDeleteBy, - pisSingleton, - pfromSingleton, - pmapMaybe, - PAlternative (..), - ppureIf, - pltBy, - pinsertUniqueBy, - ptryFromRedeemer, - passert, pisNothing, pisDNothing, - psymbolValueOf', + ptoScottEncodingT, + ptaggedSymbolValueOf, + ptag, + puntag, ) where -import Plutarch.Api.V1 ( - KeyGuarantees (Unsorted), - PPOSIXTime, - PRedeemer, - PValidatorHash, - ) -import Plutarch.Api.V1.AssocMap (PMap, plookup) import Plutarch.Api.V2 ( AmountGuarantees, + KeyGuarantees, PCurrencySymbol, PMaybeData (PDNothing), - PScriptHash, - PScriptPurpose, - PTokenName, PValue, ) -import Plutarch.Extra.Applicative (PApplicative (ppure)) -import Plutarch.Extra.Category (PCategory (pidentity)) -import Plutarch.Extra.Functor (PFunctor (PSubcategory, pfmap)) -import Plutarch.Extra.Maybe (pjust, pnothing) -import Plutarch.Extra.Ord (PComparator, POrdering (PLT), pcompareBy, pequateBy) -import Plutarch.Extra.Time (PCurrentTime (PCurrentTime)) -import Plutarch.Unsafe (punsafeCoerce) +import Plutarch.Extra.AssetClass (PAssetClass, PAssetClassData, ptoScottEncoding) +import Plutarch.Extra.Tagged (PTagged) +import Plutarch.Extra.Value (psymbolValueOf) +import Plutarch.Unsafe (punsafeDowncast) import PlutusLedgerApi.V2 ( Address (Address), Credential (ScriptCredential), - ScriptHash (ScriptHash), - TokenName (TokenName), - ValidatorHash (ValidatorHash), + ValidatorHash, ) -{- Functions which should (probably) not be upstreamed - All of these functions are quite inefficient. --} - -{- | Safely convert a 'ValidatorHash' into a 'TokenName'. This can be useful for tagging - tokens for extra safety. - - @since 0.1.0 --} -validatorHashToTokenName :: ValidatorHash -> TokenName -validatorHashToTokenName (ValidatorHash hash) = TokenName hash - -{- | Safely convert a 'PValidatorHash' into a 'PTokenName'. This can be useful for tagging - tokens for extra safety. - - @since 1.0.0 --} -pvalidatorHashToTokenName :: forall (s :: S). Term s (PValidatorHash :--> PTokenName) -pvalidatorHashToTokenName = phoistAcyclic $ plam punsafeCoerce - -{- | Safely convert a 'PScriptHash' into a 'PTokenName'. This can be useful for tagging - tokens for extra safety. - - @since 1.0.0 --} -scriptHashToTokenName :: ScriptHash -> TokenName -scriptHashToTokenName (ScriptHash hash) = TokenName hash - -{- | Safely convert a 'PScriptHash' into a 'PTokenName'. This can be useful for tagging - tokens for extra safety. - - @since 1.0.0 --} -pscriptHashToTokenName :: forall (s :: S). Term s PScriptHash -> Term s PTokenName -pscriptHashToTokenName = punsafeCoerce - {- | Create an 'Address' from a given 'ValidatorHash' with no 'PlutusLedgerApi.V1.Credential.StakingCredential'. @since 0.1.0 @@ -110,62 +43,6 @@ pscriptHashToTokenName = punsafeCoerce validatorHashToAddress :: ValidatorHash -> Address validatorHashToAddress vh = Address (ScriptCredential vh) Nothing -{- | Compare two 'PAsData' value, return true if the first one is less than the second one. - - @since 0.2.0 --} -pltAsData :: - forall (a :: PType) (s :: S). - (POrd a, PIsData a) => - Term s (PAsData a :--> PAsData a :--> PBool) -pltAsData = phoistAcyclic $ - plam $ - \(pfromData -> l) (pfromData -> r) -> l #< r - -{- | Extract data stored in a 'PBuiltinPair' and call a function to process it. - - @since 0.2.0 --} -withBuiltinPairAsData :: - forall (a :: PType) (b :: PType) (c :: PType) (s :: S). - (PIsData a, PIsData b) => - (Term s a -> Term s b -> Term s c) -> - Term - s - (PBuiltinPair (PAsData a) (PAsData b)) -> - Term s c -withBuiltinPairAsData f p = - let a = pfromData $ pfstBuiltin # p - b = pfromData $ psndBuiltin # p - in f a b - --- | @since 1.0.0 -plistEqualsBy :: - forall - (list1 :: PType -> PType) - (list2 :: PType -> PType) - (a :: PType) - (b :: PType) - (s :: S). - (PIsListLike list1 a, PIsListLike list2 b) => - Term s ((a :--> b :--> PBool) :--> list1 a :--> list2 b :--> PBool) -plistEqualsBy = phoistAcyclic $ - plam $ \eq -> pfix #$ plam $ \self l1 l2 -> - pelimList - ( \x xs -> - pelimList - ( \y ys -> - -- Avoid comparison if two lists have different length. - self # xs # ys #&& eq # x # y - ) - -- l2 is empty, but l1 is not. - (pconstant False) - l2 - ) - -- l1 is empty, so l2 should be empty as well. - (pnull # l2) - l1 - -- | @since 1.0.0 pstringIntercalate :: forall (s :: S). @@ -183,225 +60,6 @@ punwords :: Term s PString punwords = pstringIntercalate " " --- | @since 1.0.0 -pcurrentTimeDuration :: - forall (s :: S). - Term - s - ( PCurrentTime - :--> PPOSIXTime - ) -pcurrentTimeDuration = phoistAcyclic $ - plam $ - flip pmatch $ - \(PCurrentTime lb ub) -> ub - lb - -{- | / O(n) /. Remove the first occurance of a value from the given list. - - @since 1.0.0 --} -pdelete :: - forall (a :: PType) (list :: PType -> PType) (s :: S). - (PEq a, PIsListLike list a) => - Term s (a :--> list a :--> PMaybe (list a)) -pdelete = phoistAcyclic $ pdeleteBy # plam (#==) - --- | @since 1.0.0 -pdeleteBy :: - forall (a :: PType) (list :: PType -> PType) (s :: S). - (PIsListLike list a) => - Term s ((a :--> a :--> PBool) :--> a :--> list a :--> PMaybe (list a)) -pdeleteBy = phoistAcyclic $ - plam $ \f' x -> plet (f' # x) $ \f -> - precList - ( \self h t -> - pif - (f # h) - (pjust # t) - (pfmap # (pcons # h) # (self # t)) - ) - (const pnothing) - --- | @since 1.0.0 -pmustDeleteBy :: - forall (a :: PType) (list :: PType -> PType) (s :: S). - (PIsListLike list a) => - Term s ((a :--> a :--> PBool) :--> a :--> list a :--> list a) -pmustDeleteBy = phoistAcyclic $ - plam $ \f' x -> plet (f' # x) $ \f -> - precList - ( \self h t -> - pif - (f # h) - t - (pcons # h #$ self # t) - ) - (const $ ptraceError "Cannot delete element") - -{- | / O(1) /.Return true if the given list has only one element. - - @since 1.0.0 --} -pisSingleton :: - forall (a :: PType) (list :: PType -> PType) (s :: S). - (PIsListLike list a) => - Term s (list a :--> PBool) -pisSingleton = - phoistAcyclic $ - precList - (\_ _ t -> pnull # t) - (const $ pconstant False) - -{- Throws an error if the given list contains zero or more than one elements. - Otherwise returns the only element. - - @since 1.0.0 --} -pfromSingleton :: - forall (a :: PType) (list :: PType -> PType) (s :: S). - (PIsListLike list a) => - Term s (list a :--> a) -pfromSingleton = - phoistAcyclic $ - precList - ( \_ h t -> - pif - (pnull # t) - h - (ptraceError "More than one element") - ) - (const $ ptraceError "Empty list") - -{- | A version of 'pmap' which can throw out elements and change the list type - along the way. - - @since 1.0.0 --} -pmapMaybe :: - forall - (listO :: PType -> PType) - (b :: PType) - (listI :: PType -> PType) - (a :: PType) - (s :: S). - (PIsListLike listI a, PIsListLike listO b) => - Term s ((a :--> PMaybe b) :--> listI a :--> listO b) -pmapMaybe = phoistAcyclic $ - plam $ \f -> - precList - ( \self h t -> - pmatch - (f # h) - ( \case - PJust x -> pcons # x - PNothing -> pidentity - ) - # (self # t) - ) - (const pnil) - -infixl 3 #<|> - --- | @since 1.0.0 -class (PApplicative f) => PAlternative (f :: PType -> PType) where - (#<|>) :: - forall (a :: PType) (s :: S). - (PSubcategory f a) => - Term s (f a :--> f a :--> f a) - pempty :: - forall (a :: PType) (s :: S). - (PSubcategory f a) => - Term s (f a) - --- | @since 1.0.0 -instance PAlternative PMaybe where - (#<|>) = phoistAcyclic $ - plam $ \a b -> pmatch a $ \case - PNothing -> b - PJust _ -> a - pempty = pnothing - --- | @since 1.0.0 -ppureIf :: - forall - (f :: PType -> PType) - (a :: PType) - (s :: S). - (PAlternative f, PSubcategory f a) => - Term s (PBool :--> a :--> f a) -ppureIf = phoistAcyclic $ - plam $ \cond x -> - pif - cond - (ppure # x) - pempty - -{- | Less then check using a `PComparator`. - - @ since 1.0.0 --} -pltBy :: - forall (a :: PType) (s :: S). - Term - s - ( PComparator a - :--> a - :--> a - :--> PBool - ) -pltBy = phoistAcyclic $ - plam $ \c x y -> - pcompareBy # c # x # y #== pcon PLT - --- | @since 1.0.0 -pinsertUniqueBy :: - forall (list :: PType -> PType) (a :: PType) (s :: S). - (PIsListLike list a) => - Term s (PComparator a :--> a :--> list a :--> list a) -pinsertUniqueBy = phoistAcyclic $ - plam $ \c x -> - let lt = pltBy # c - eq = pequateBy # c - in precList - ( \self h t -> - let ensureUniqueness = - pif - (eq # x # h) - (ptraceError "inserted value already exists") - next = - pif - (lt # x # h) - (pcons # x #$ pcons # h # t) - (pcons # h #$ self # t) - in ensureUniqueness next - ) - (const $ psingleton # x) - --- | @since 1.0.0 -ptryFromRedeemer :: - forall (r :: PType) (s :: S). - (PTryFrom PData r) => - Term - s - ( PScriptPurpose - :--> PMap 'Unsorted PScriptPurpose PRedeemer - :--> PMaybe r - ) -ptryFromRedeemer = phoistAcyclic $ - plam $ \p m -> - pfmap - # plam (flip ptryFrom fst . pto) - # (plookup # p # m) - --- | @since 1.0.0 -passert :: - forall (a :: PType) (s :: S). - Term s PString -> - Term s PBool -> - Term s a -> - Term s a -passert msg cond x = pif cond x $ ptraceError msg - -- | @since 1.0.0 pisNothing :: forall (a :: PType) (s :: S). @@ -422,45 +80,38 @@ pisDNothing = phoistAcyclic $ PDNothing _ -> pconstant True _ -> pconstant False -{- | Get the negative and positive amount of a particular 'CurrencySymbol', and - return nothing if it doesn't exist in the value. +-- | @since 1.0.0 +ptoScottEncodingT :: + forall {k :: Type} (unit :: k) (s :: S). + Term s (PTagged unit PAssetClassData :--> PTagged unit PAssetClass) +ptoScottEncodingT = phoistAcyclic $ + plam $ \d -> + punsafeDowncast $ ptoScottEncoding #$ pto d + +{- | Get the sum of all values belonging to a particular tagged 'CurrencySymbol'. @since 1.0.0 -} -psymbolValueOf' :: +ptaggedSymbolValueOf :: forall + {k :: Type} + (unit :: k) (keys :: KeyGuarantees) (amounts :: AmountGuarantees) (s :: S). - Term - s - ( PCurrencySymbol - :--> PValue keys amounts - :--> PMaybe - ( PPair - -- Positive amount - PInteger - -- Negative amount - PInteger - ) - ) -psymbolValueOf' = phoistAcyclic $ - plam $ \sym value -> - let tnMap = plookup # sym # pto value - f = - plam $ - ( pfoldr - # plam - ( \x r -> - let q = pfromData $ psndBuiltin # x - in pmatch r $ \(PPair p n) -> - pif - (0 #< q) - (pcon $ PPair (p + q) n) - (pcon $ PPair p (n + q)) - ) - # pcon (PPair 0 0) - # - ) - . pto - in pfmap # f # tnMap + Term s (PTagged unit PCurrencySymbol :--> (PValue keys amounts :--> PInteger)) +ptaggedSymbolValueOf = phoistAcyclic $ plam $ \tcs -> psymbolValueOf # pto tcs + +-- | @since 1.0.0 +ptag :: + forall {k :: Type} (tag :: k) (a :: PType) (s :: S). + Term s a -> + Term s (PTagged tag a) +ptag = punsafeDowncast + +-- | @since 1.0.0 +puntag :: + forall {k :: Type} (tag :: k) (a :: PType) (s :: S). + Term s (PTagged tag a) -> + Term s a +puntag = pto diff --git a/bench.csv b/bench.csv index bfbade0..0483694 100644 --- a/bench.csv +++ b/bench.csv @@ -1,483 +1,503 @@ name,cpu,mem,size -Agora/Effects/Treasury Withdrawal Effect/effect/Simple,216491233,584406,3880 -Agora/Effects/Treasury Withdrawal Effect/effect/Simple with multiple treasuries ,307752363,787074,4312 -Agora/Effects/Treasury Withdrawal Effect/effect/Mixed Assets,300492604,786706,4250 -Agora/Effects/Governor Mutation Effect/validator/valid new governor datum/governor validator should pass,124187615,349163,11718 -Agora/Effects/Governor Mutation Effect/validator/valid new governor datum/effect validator should pass,145816056,387807,4684 -Agora/Stake/policy/create/valid/stake owner: pub key,77468330,198844,3556 -Agora/Stake/policy/create/valid/stake owner: script,90607586,237423,3591 -Agora/Stake/validator/destroy/legal/One stake/stake validator,100147548,269527,7240 -Agora/Stake/validator/destroy/legal/One stake/stake policy,29665872,85956,3543 -Agora/Stake/validator/destroy/legal/Multiple stake/stake validator,653259180,1567111,10493 -Agora/Stake/validator/destroy/legal/Multiple stake/stake policy,292337523,820464,6795 -Agora/Stake/validator/destroy/illegal/Destroy locked stakes/stake policy,292337523,820464,6856 -Agora/Stake/validator/destroy/illegal/not authorized by owner/stake policy,292337523,820464,6764 -Agora/Stake/validator/destroy/illegal/not authorized by owner/stake policy,292337523,820464,6795 -Agora/Stake/validator/stakeDepositWithdraw deposit,142600267,368376,7355 -Agora/Stake/validator/stakeDepositWithdraw withdraw,142600267,368376,7347 -Agora/Stake/validator/set delegate/override existing delegate,174762504,439707,7486 -Agora/Stake/validator/set delegate/remove existing delegate,164862019,415117,7416 -Agora/Stake/validator/set delegate/set delegate to something,172333516,432607,7416 -Agora/Proposal/policy (proposal creation)/legal/proposal,30050955,75784,2649 -Agora/Proposal/policy (proposal creation)/legal/governor,276624956,722480,12216 -Agora/Proposal/policy (proposal creation)/legal/stake,299062773,743108,8183 -Agora/Proposal/policy (proposal creation)/illegal/invalid next proposal id/proposal,30050955,75784,2649 -Agora/Proposal/policy (proposal creation)/illegal/invalid next proposal id/stake,299062773,743108,8183 -Agora/Proposal/policy (proposal creation)/illegal/use other's stake/proposal,30050955,75784,2617 -Agora/Proposal/policy (proposal creation)/illegal/use other's stake/governor,276624956,722480,12185 -Agora/Proposal/policy (proposal creation)/illegal/altered stake/proposal,30050955,75784,2649 -Agora/Proposal/policy (proposal creation)/illegal/invalid stake locks/proposal,30050955,75784,2657 -Agora/Proposal/policy (proposal creation)/illegal/invalid stake locks/governor,276624956,722480,12224 -Agora/Proposal/policy (proposal creation)/illegal/has reached maximum proposals limit/proposal,30050955,75784,2669 -Agora/Proposal/policy (proposal creation)/illegal/has reached maximum proposals limit/stake,311761209,779324,8213 -Agora/Proposal/policy (proposal creation)/illegal/loose time range/proposal,30050955,75784,2649 -Agora/Proposal/policy (proposal creation)/illegal/loose time range/stake,299062773,743108,8183 -Agora/Proposal/policy (proposal creation)/illegal/open time range/proposal,30050955,75784,2645 -Agora/Proposal/policy (proposal creation)/illegal/open time range/stake,299062773,743108,8179 -Agora/Proposal/policy (proposal creation)/illegal/invalid proposal status/VotingReady/proposal,30050955,75784,2649 -Agora/Proposal/policy (proposal creation)/illegal/invalid proposal status/VotingReady/stake,299062773,743108,8183 -Agora/Proposal/policy (proposal creation)/illegal/invalid proposal status/Locked/proposal,30050955,75784,2649 -Agora/Proposal/policy (proposal creation)/illegal/invalid proposal status/Locked/stake,299062773,743108,8183 -Agora/Proposal/policy (proposal creation)/illegal/invalid proposal status/Finished/proposal,30050955,75784,2649 -Agora/Proposal/policy (proposal creation)/illegal/invalid proposal status/Finished/stake,299062773,743108,8183 -Agora/Proposal/validator/cosignature/legal/proposal,201848764,555553,11866 -Agora/Proposal/validator/cosignature/legal/stake,256214245,661528,7982 -Agora/Proposal/validator/cosignature/illegal/insufficient staked amount/stake,256214245,661528,7982 -Agora/Proposal/validator/cosignature/illegal/proposal locks not updated/proposal,201848764,555553,11860 -Agora/Proposal/validator/cosignature/illegal/duplicate cosigners/stake,262563463,679636,7999 -Agora/Proposal/validator/cosignature/illegal/cosigners not updated/stake,256214245,661528,7948 -Agora/Proposal/validator/cosignature/illegal/cosign after draft/(negative test)/stake,256214245,661528,7982 -Agora/Proposal/validator/cosignature/illegal/cosign after draft/(negative test)/stake,256214245,661528,7982 -Agora/Proposal/validator/cosignature/illegal/cosign after draft/(negative test)/stake,256214245,661528,7982 -Agora/Proposal/validator/voting/legal/different number of stakes/1 stakes/by owner/proposal,217201178,603628,11718 -Agora/Proposal/validator/voting/legal/different number of stakes/1 stakes/by owner/stake,270982879,701289,7845 -Agora/Proposal/validator/voting/legal/different number of stakes/1 stakes/by delegatee/proposal,217201178,603628,11718 -Agora/Proposal/validator/voting/legal/different number of stakes/1 stakes/by delegatee/stake,277809774,718445,7845 -Agora/Proposal/validator/voting/legal/different number of stakes/3 stakes/by owner/proposal,323914032,882782,12933 -Agora/Proposal/validator/voting/legal/different number of stakes/3 stakes/by owner/stake,561081905,1375723,9060 -Agora/Proposal/validator/voting/legal/different number of stakes/3 stakes/by delegatee/proposal,323914032,882782,12933 -Agora/Proposal/validator/voting/legal/different number of stakes/3 stakes/by delegatee/stake,567908800,1392879,9060 -Agora/Proposal/validator/voting/legal/different number of stakes/5 stakes/by owner/proposal,430626886,1161936,14148 -Agora/Proposal/validator/voting/legal/different number of stakes/5 stakes/by owner/stake,851180931,2050157,10275 -Agora/Proposal/validator/voting/legal/different number of stakes/5 stakes/by delegatee/proposal,430626886,1161936,14148 -Agora/Proposal/validator/voting/legal/different number of stakes/5 stakes/by delegatee/stake,858007826,2067313,10275 -Agora/Proposal/validator/voting/legal/different number of stakes/7 stakes/by owner/proposal,537339740,1441090,15362 -Agora/Proposal/validator/voting/legal/different number of stakes/7 stakes/by owner/stake,1141279957,2724591,11489 -Agora/Proposal/validator/voting/legal/different number of stakes/7 stakes/by delegatee/proposal,537339740,1441090,15362 -Agora/Proposal/validator/voting/legal/different number of stakes/7 stakes/by delegatee/stake,1148106852,2741747,11489 -Agora/Proposal/validator/voting/legal/different number of stakes/9 stakes/by owner/proposal,644052594,1720244,16577 -Agora/Proposal/validator/voting/legal/different number of stakes/9 stakes/by owner/stake,1431378983,3399025,12704 -Agora/Proposal/validator/voting/legal/different number of stakes/9 stakes/by delegatee/proposal,644052594,1720244,16577 -Agora/Proposal/validator/voting/legal/different number of stakes/9 stakes/by delegatee/stake,1438205878,3416181,12704 -Agora/Proposal/validator/voting/legal/transparent non-GT tokens/proposal,217201178,603628,11718 -Agora/Proposal/validator/voting/legal/transparent non-GT tokens/stake,270982879,701289,7845 -Agora/Proposal/validator/voting/illegal/vote for nonexistent outcome/stake,270982879,701289,7850 -Agora/Proposal/validator/voting/illegal/unauthorized tx/proposal,217201178,603628,11718 -Agora/Proposal/validator/voting/illegal/more than one proposals/stake,270982879,701289,7850 -Agora/Proposal/validator/voting/illegal/locks not added/proposal,430626886,1161936,14118 -Agora/Proposal/validator/voting/illegal/attempt to burn stakes/proposal,407560031,1110316,13089 -Agora/Proposal/validator/voting/illegal/insufficient staked amount/stake,270982879,701289,7822 -Agora/Proposal/validator/voting/illegal/insufficient staked amount/stake,851180931,2050157,10187 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Draft to VotingReady/proposal,241769498,672925,12332 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from VotingReady to Locked/proposal,221156600,615910,12095 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Locked to Finished/proposal,234564233,643058,13366 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Locked to Finished/governor,403373267,1065069,13186 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Locked to Finished/authority,87514895,216737,3652 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Draft to VotingReady/proposal,237958208,660697,12053 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from VotingReady to Locked/proposal,217345310,603682,11816 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Locked to Finished/proposal,230752943,630830,12908 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Locked to Finished/governor,401005973,1057563,12821 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Locked to Finished/authority,82449293,203081,3287 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to failed state/from Draft to Finished/proposal,212215847,594571,12088 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to failed state/from VotingReady to Finished/proposal,210487464,584281,12089 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to failed state/from Locked to Finished/proposal,222674368,615093,12089 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to failed state/from Draft to Finished/proposal,208404557,582343,11809 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to failed state/from VotingReady to Finished/proposal,206676174,572053,11810 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to failed state/from Locked to Finished/proposal,218863078,602865,11810 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/advance finished proposals/(negative test)/authority,87514895,216737,3652 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/advance finished proposals/(negative test)/authority,82449293,203081,3287 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/to next state too late/from Locked/governor,403373267,1065069,13186 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/to next state too late/from Locked/authority,87514895,216737,3652 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/to next state too late/from Locked/governor,401005973,1057563,12821 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/to next state too late/from Locked/authority,82449293,203081,3287 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/forget to mint GATs/proposal,230752943,630830,12262 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/mint GATs for wrong validators/proposal,230752943,630830,12908 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/mint GATs for wrong validators/authority,82449293,203081,3287 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/mint GATs with bad token name/proposal,230752943,630830,12940 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/mint GATs with bad token name/authority,82449293,203081,3319 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/wrong GAT datum/proposal,230752943,630830,12902 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/wrong GAT datum/authority,82449293,203081,3281 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/invalid governor output datum/proposal,230752943,630830,12908 -Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/invalid governor output datum/authority,82449293,203081,3287 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Draft to VotingReady/proposal,315994218,877227,13248 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from VotingReady to Locked/proposal,299076206,830200,13011 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Locked to Finished/proposal,308788953,847360,14282 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Locked to Finished/governor,445108495,1182301,13797 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Locked to Finished/authority,87514895,216737,4263 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Draft to VotingReady/proposal,308371638,852771,12687 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from VotingReady to Locked/proposal,291453626,805744,12450 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Locked to Finished/proposal,301166373,822904,13543 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Locked to Finished/governor,440986588,1168681,13245 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Locked to Finished/authority,82449293,203081,3711 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to failed state/from Draft to Finished/proposal,286440567,798873,13004 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to failed state/from VotingReady to Finished/proposal,284712184,788583,13005 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to failed state/from Locked to Finished/proposal,296899088,819395,13005 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to failed state/from Draft to Finished/proposal,278817987,774417,12443 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to failed state/from VotingReady to Finished/proposal,277089604,764127,12444 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to failed state/from Locked to Finished/proposal,289276508,794939,12444 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/advance finished proposals/(negative test)/authority,87514895,216737,4263 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/advance finished proposals/(negative test)/authority,82449293,203081,3711 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/to next state too late/from Locked/governor,445108495,1182301,13797 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/to next state too late/from Locked/authority,87514895,216737,4263 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/to next state too late/from Locked/governor,440986588,1168681,13245 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/to next state too late/from Locked/authority,82449293,203081,3711 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/forget to mint GATs/proposal,301166373,822904,12897 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/mint GATs for wrong validators/proposal,301166373,822904,13543 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/mint GATs for wrong validators/authority,82449293,203081,3711 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/mint GATs with bad token name/proposal,301166373,822904,13575 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/mint GATs with bad token name/authority,82449293,203081,3743 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/wrong GAT datum/proposal,301166373,822904,13537 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/wrong GAT datum/authority,82449293,203081,3705 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/invalid governor output datum/proposal,301166373,822904,13543 -Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/invalid governor output datum/authority,82449293,203081,3711 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Draft to VotingReady/proposal,538668378,1490133,15995 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from VotingReady to Locked/proposal,532835024,1473070,15758 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Locked to Finished/proposal,531463113,1460266,17029 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Locked to Finished/governor,570314179,1533997,15628 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Locked to Finished/authority,87514895,216737,6094 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Draft to VotingReady/proposal,519611928,1428993,14594 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from VotingReady to Locked/proposal,513778574,1411930,14357 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Locked to Finished/proposal,512406663,1399126,15450 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Locked to Finished/governor,560928433,1502035,14516 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Locked to Finished/authority,82449293,203081,4982 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to failed state/from Draft to Finished/proposal,509114727,1411779,15751 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to failed state/from VotingReady to Finished/proposal,507386344,1401489,15752 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to failed state/from Locked to Finished/proposal,519573248,1432301,15752 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to failed state/from Draft to Finished/proposal,490058277,1350639,14350 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to failed state/from VotingReady to Finished/proposal,488329894,1340349,14351 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to failed state/from Locked to Finished/proposal,500516798,1371161,14351 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/advance finished proposals/(negative test)/authority,87514895,216737,6094 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/advance finished proposals/(negative test)/authority,82449293,203081,4982 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/to next state too late/from Locked/governor,570314179,1533997,15628 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/to next state too late/from Locked/authority,87514895,216737,6094 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/to next state too late/from Locked/governor,560928433,1502035,14516 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/to next state too late/from Locked/authority,82449293,203081,4982 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/forget to mint GATs/proposal,512406663,1399126,14804 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/mint GATs for wrong validators/proposal,512406663,1399126,15450 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/mint GATs for wrong validators/authority,82449293,203081,4982 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/mint GATs with bad token name/proposal,512406663,1399126,15482 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/mint GATs with bad token name/authority,82449293,203081,5014 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/wrong GAT datum/proposal,512406663,1399126,15444 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/wrong GAT datum/authority,82449293,203081,4976 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/invalid governor output datum/proposal,512406663,1399126,15450 -Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/invalid governor output datum/authority,82449293,203081,4982 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Draft to VotingReady/proposal,421896692,1152021,13833 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from VotingReady to Locked/proposal,251507320,699638,12506 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Locked to Finished/proposal,264914953,726786,13776 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Locked to Finished/governor,418246563,1106933,13459 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Locked to Finished/authority,87514895,216737,3925 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Draft to VotingReady/proposal,418085402,1139793,13552 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from VotingReady to Locked/proposal,247696030,687410,12225 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Locked to Finished/proposal,261103663,714558,13317 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Locked to Finished/governor,415879269,1099427,13094 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Locked to Finished/authority,82449293,203081,3560 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to failed state/from Draft to Finished/proposal,242566567,678299,12498 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to failed state/from VotingReady to Finished/proposal,240838184,668009,12499 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to failed state/from Locked to Finished/proposal,253025088,698821,12499 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to failed state/from Draft to Finished/proposal,238755277,666071,12218 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to failed state/from VotingReady to Finished/proposal,237026894,655781,12219 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to failed state/from Locked to Finished/proposal,249213798,686593,12219 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/advance finished proposals/(negative test)/authority,87514895,216737,3925 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/advance finished proposals/(negative test)/authority,82449293,203081,3560 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/to next state too late/from Locked/governor,418246563,1106933,13459 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/to next state too late/from Locked/authority,87514895,216737,3925 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/to next state too late/from Locked/governor,415879269,1099427,13094 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/to next state too late/from Locked/authority,82449293,203081,3560 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/forget to mint GATs/proposal,261103663,714558,12672 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/mint GATs for wrong validators/proposal,261103663,714558,13317 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/mint GATs for wrong validators/authority,82449293,203081,3560 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/mint GATs with bad token name/proposal,261103663,714558,13349 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/mint GATs with bad token name/authority,82449293,203081,3592 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/wrong GAT datum/proposal,261103663,714558,13311 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/wrong GAT datum/authority,82449293,203081,3554 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/invalid governor output datum/proposal,261103663,714558,13317 -Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/invalid governor output datum/authority,82449293,203081,3560 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Draft to VotingReady/proposal,496121412,1356323,14748 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from VotingReady to Locked/proposal,329426926,913928,13421 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Locked to Finished/proposal,339139673,931088,14692 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Locked to Finished/governor,459981791,1224165,14070 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Locked to Finished/authority,87514895,216737,4536 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Draft to VotingReady/proposal,488498832,1331867,14188 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from VotingReady to Locked/proposal,321804346,889472,12860 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Locked to Finished/proposal,331517093,906632,13953 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Locked to Finished/governor,455859884,1210545,13518 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Locked to Finished/authority,82449293,203081,3984 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to failed state/from Draft to Finished/proposal,316791287,882601,13414 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to failed state/from VotingReady to Finished/proposal,315062904,872311,13415 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to failed state/from Locked to Finished/proposal,327249808,903123,13415 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to failed state/from Draft to Finished/proposal,309168707,858145,12853 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to failed state/from VotingReady to Finished/proposal,307440324,847855,12854 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to failed state/from Locked to Finished/proposal,319627228,878667,12854 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/advance finished proposals/(negative test)/authority,87514895,216737,4536 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/advance finished proposals/(negative test)/authority,82449293,203081,3984 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/to next state too late/from Locked/governor,459981791,1224165,14070 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/to next state too late/from Locked/authority,87514895,216737,4536 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/to next state too late/from Locked/governor,455859884,1210545,13518 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/to next state too late/from Locked/authority,82449293,203081,3984 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/forget to mint GATs/proposal,331517093,906632,13307 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/mint GATs for wrong validators/proposal,331517093,906632,13953 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/mint GATs for wrong validators/authority,82449293,203081,3984 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/mint GATs with bad token name/proposal,331517093,906632,13985 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/mint GATs with bad token name/authority,82449293,203081,4016 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/wrong GAT datum/proposal,331517093,906632,13947 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/wrong GAT datum/authority,82449293,203081,3978 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/invalid governor output datum/proposal,331517093,906632,13953 -Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/invalid governor output datum/authority,82449293,203081,3984 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Draft to VotingReady/proposal,718795572,1969229,17494 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from VotingReady to Locked/proposal,563185744,1556798,16167 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Locked to Finished/proposal,561813833,1543994,17438 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Locked to Finished/governor,585187475,1575861,15901 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Locked to Finished/authority,87514895,216737,6367 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Draft to VotingReady/proposal,699739122,1908089,16094 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from VotingReady to Locked/proposal,544129294,1495658,14766 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Locked to Finished/proposal,542757383,1482854,15859 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Locked to Finished/governor,575801729,1543899,14789 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Locked to Finished/authority,82449293,203081,5255 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to failed state/from Draft to Finished/proposal,539465447,1495507,16160 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to failed state/from VotingReady to Finished/proposal,537737064,1485217,16161 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to failed state/from Locked to Finished/proposal,549923968,1516029,16161 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to failed state/from Draft to Finished/proposal,520408997,1434367,14759 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to failed state/from VotingReady to Finished/proposal,518680614,1424077,14760 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to failed state/from Locked to Finished/proposal,530867518,1454889,14760 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/advance finished proposals/(negative test)/authority,87514895,216737,6367 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/advance finished proposals/(negative test)/authority,82449293,203081,5255 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/to next state too late/from Locked/governor,585187475,1575861,15901 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/to next state too late/from Locked/authority,87514895,216737,6367 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/to next state too late/from Locked/governor,575801729,1543899,14789 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/to next state too late/from Locked/authority,82449293,203081,5255 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/forget to mint GATs/proposal,542757383,1482854,15213 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/mint GATs for wrong validators/proposal,542757383,1482854,15859 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/mint GATs for wrong validators/authority,82449293,203081,5255 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/mint GATs with bad token name/proposal,542757383,1482854,15891 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/mint GATs with bad token name/authority,82449293,203081,5287 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/wrong GAT datum/proposal,542757383,1482854,15853 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/wrong GAT datum/authority,82449293,203081,5249 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/invalid governor output datum/proposal,542757383,1482854,15859 -Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/invalid governor output datum/authority,82449293,203081,5255 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Draft to VotingReady/proposal,662219128,1796582,15709 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from VotingReady to Locked/proposal,289445720,804298,13017 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Locked to Finished/proposal,302853353,831446,14288 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Locked to Finished/governor,436838183,1159263,13801 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Locked to Finished/authority,87514895,216737,4267 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Draft to VotingReady/proposal,658407838,1784354,15430 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from VotingReady to Locked/proposal,285634430,792070,12737 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Locked to Finished/proposal,299042063,819218,13829 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Locked to Finished/governor,434470889,1151757,13435 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Locked to Finished/authority,82449293,203081,3901 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to failed state/from Draft to Finished/proposal,280504967,782959,13010 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to failed state/from VotingReady to Finished/proposal,278776584,772669,13011 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to failed state/from Locked to Finished/proposal,290963488,803481,13011 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to failed state/from Draft to Finished/proposal,276693677,770731,12730 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to failed state/from VotingReady to Finished/proposal,274965294,760441,12731 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to failed state/from Locked to Finished/proposal,287152198,791253,12731 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/advance finished proposals/(negative test)/authority,87514895,216737,4267 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/advance finished proposals/(negative test)/authority,82449293,203081,3901 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/to next state too late/from Locked/governor,436838183,1159263,13801 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/to next state too late/from Locked/authority,87514895,216737,4267 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/to next state too late/from Locked/governor,434470889,1151757,13435 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/to next state too late/from Locked/authority,82449293,203081,3901 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/forget to mint GATs/proposal,299042063,819218,13184 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/mint GATs for wrong validators/proposal,299042063,819218,13829 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/mint GATs for wrong validators/authority,82449293,203081,3901 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/mint GATs with bad token name/proposal,299042063,819218,13862 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/mint GATs with bad token name/authority,82449293,203081,3933 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/wrong GAT datum/proposal,299042063,819218,13823 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/wrong GAT datum/authority,82449293,203081,3895 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/invalid governor output datum/proposal,299042063,819218,13829 -Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/invalid governor output datum/authority,82449293,203081,3901 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Draft to VotingReady/proposal,736443848,2000884,16625 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from VotingReady to Locked/proposal,367365326,1018588,13932 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Locked to Finished/proposal,377078073,1035748,15203 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Locked to Finished/governor,478573411,1276495,14411 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Locked to Finished/authority,87514895,216737,4877 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Draft to VotingReady/proposal,728821268,1976428,16065 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from VotingReady to Locked/proposal,359742746,994132,13373 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Locked to Finished/proposal,369455493,1011292,14465 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Locked to Finished/governor,474451504,1262875,13859 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Locked to Finished/authority,82449293,203081,4325 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to failed state/from Draft to Finished/proposal,354729687,987261,13925 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to failed state/from VotingReady to Finished/proposal,353001304,976971,13926 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to failed state/from Locked to Finished/proposal,365188208,1007783,13926 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to failed state/from Draft to Finished/proposal,347107107,962805,13366 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to failed state/from VotingReady to Finished/proposal,345378724,952515,13367 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to failed state/from Locked to Finished/proposal,357565628,983327,13367 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/advance finished proposals/(negative test)/authority,87514895,216737,4877 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/advance finished proposals/(negative test)/authority,82449293,203081,4325 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/to next state too late/from Locked/governor,478573411,1276495,14411 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/to next state too late/from Locked/authority,87514895,216737,4877 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/to next state too late/from Locked/governor,474451504,1262875,13859 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/to next state too late/from Locked/authority,82449293,203081,4325 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/forget to mint GATs/proposal,369455493,1011292,13820 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/mint GATs for wrong validators/proposal,369455493,1011292,14465 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/mint GATs for wrong validators/authority,82449293,203081,4325 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/mint GATs with bad token name/proposal,369455493,1011292,14497 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/mint GATs with bad token name/authority,82449293,203081,4357 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/wrong GAT datum/proposal,369455493,1011292,14459 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/wrong GAT datum/authority,82449293,203081,4319 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/invalid governor output datum/proposal,369455493,1011292,14465 -Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/invalid governor output datum/authority,82449293,203081,4325 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Draft to VotingReady/proposal,959118008,2613790,19372 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from VotingReady to Locked/proposal,601124144,1661458,16679 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Locked to Finished/proposal,599752233,1648654,17950 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Locked to Finished/governor,603779095,1628191,16242 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Locked to Finished/authority,87514895,216737,6708 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Draft to VotingReady/proposal,940061558,2552650,17971 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from VotingReady to Locked/proposal,582067694,1600318,15279 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Locked to Finished/proposal,580695783,1587514,16371 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Locked to Finished/governor,594393349,1596229,15130 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Locked to Finished/authority,82449293,203081,5596 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to failed state/from Draft to Finished/proposal,577403847,1600167,16672 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to failed state/from VotingReady to Finished/proposal,575675464,1589877,16673 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to failed state/from Locked to Finished/proposal,587862368,1620689,16673 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to failed state/from Draft to Finished/proposal,558347397,1539027,15272 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to failed state/from VotingReady to Finished/proposal,556619014,1528737,15273 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to failed state/from Locked to Finished/proposal,568805918,1559549,15273 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/advance finished proposals/(negative test)/authority,87514895,216737,6708 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/advance finished proposals/(negative test)/authority,82449293,203081,5596 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/to next state too late/from Locked/governor,603779095,1628191,16242 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/to next state too late/from Locked/authority,87514895,216737,6708 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/to next state too late/from Locked/governor,594393349,1596229,15130 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/to next state too late/from Locked/authority,82449293,203081,5596 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/forget to mint GATs/proposal,580695783,1587514,15725 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/mint GATs for wrong validators/proposal,580695783,1587514,16371 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/mint GATs for wrong validators/authority,82449293,203081,5596 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/mint GATs with bad token name/proposal,580695783,1587514,16403 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/mint GATs with bad token name/authority,82449293,203081,5628 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/wrong GAT datum/proposal,580695783,1587514,16365 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/wrong GAT datum/authority,82449293,203081,5590 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/invalid governor output datum/proposal,580695783,1587514,16371 -Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/invalid governor output datum/authority,82449293,203081,5596 -Agora/Proposal/validator/unlocking/legal/with 1 stakes/voter: retract votes while voting/stake,279058825,705875,8067 -Agora/Proposal/validator/unlocking/legal/with 1 stakes/voter: retract votes while voting/proposal,216327247,595640,11945 -Agora/Proposal/validator/unlocking/legal/with 1 stakes/voter: retract votes while voting by delegatee/stake,285885720,723031,8067 -Agora/Proposal/validator/unlocking/legal/with 1 stakes/voter: retract votes while voting by delegatee/proposal,216327247,595640,11945 -Agora/Proposal/validator/unlocking/legal/with 1 stakes/voter/creator: retract votes while voting/stake,289565080,736477,8083 -Agora/Proposal/validator/unlocking/legal/with 1 stakes/voter/creator: retract votes while voting/proposal,222662651,614054,11956 -Agora/Proposal/validator/unlocking/legal/with 1 stakes/creator: remove creator lock after voting/stake,280060082,709082,8070 -Agora/Proposal/validator/unlocking/legal/with 1 stakes/creator: remove creator lock after voting/proposal,184227955,507972,11949 -Agora/Proposal/validator/unlocking/legal/with 1 stakes/Voter: remove lock after voting/stake,280189803,708279,8072 -Agora/Proposal/validator/unlocking/legal/with 1 stakes/Voter: remove lock after voting/proposal,185266232,510770,11950 -Agora/Proposal/validator/unlocking/legal/with 3 stakes/voter: retract votes while voting/stake,577605005,1368019,9412 -Agora/Proposal/validator/unlocking/legal/with 3 stakes/voter: retract votes while voting/proposal,327560147,886154,13290 -Agora/Proposal/validator/unlocking/legal/with 3 stakes/voter: retract votes while voting by delegatee/stake,584431900,1385175,9412 -Agora/Proposal/validator/unlocking/legal/with 3 stakes/voter: retract votes while voting by delegatee/proposal,327560147,886154,13290 -Agora/Proposal/validator/unlocking/legal/with 3 stakes/voter/creator: retract votes while voting/stake,609123770,1459825,9450 -Agora/Proposal/validator/unlocking/legal/with 3 stakes/voter/creator: retract votes while voting/proposal,346566359,941396,13323 -Agora/Proposal/validator/unlocking/legal/with 3 stakes/creator: remove creator lock after voting/stake,578346820,1372832,9413 -Agora/Proposal/validator/unlocking/legal/with 3 stakes/creator: remove creator lock after voting/proposal,251935769,673222,13292 -Agora/Proposal/validator/unlocking/legal/with 3 stakes/Voter: remove lock after voting/stake,578735983,1370423,9417 -Agora/Proposal/validator/unlocking/legal/with 3 stakes/Voter: remove lock after voting/proposal,255050600,681616,13295 -Agora/Proposal/validator/unlocking/legal/with 5 stakes/voter: retract votes while voting/stake,895797841,2061603,10758 -Agora/Proposal/validator/unlocking/legal/with 5 stakes/voter: retract votes while voting/proposal,438793047,1176668,14636 -Agora/Proposal/validator/unlocking/legal/with 5 stakes/voter: retract votes while voting by delegatee/stake,902624736,2078759,10758 -Agora/Proposal/validator/unlocking/legal/with 5 stakes/voter: retract votes while voting by delegatee/proposal,438793047,1176668,14636 -Agora/Proposal/validator/unlocking/legal/with 5 stakes/voter/creator: retract votes while voting/stake,948329116,2214613,10818 -Agora/Proposal/validator/unlocking/legal/with 5 stakes/voter/creator: retract votes while voting/proposal,470470067,1268738,14691 -Agora/Proposal/validator/unlocking/legal/with 5 stakes/creator: remove creator lock after voting/stake,896280214,2068022,10757 -Agora/Proposal/validator/unlocking/legal/with 5 stakes/creator: remove creator lock after voting/proposal,319643583,838472,14636 -Agora/Proposal/validator/unlocking/legal/with 5 stakes/Voter: remove lock after voting/stake,896928819,2064007,10763 -Agora/Proposal/validator/unlocking/legal/with 5 stakes/Voter: remove lock after voting/proposal,324834968,852462,14641 -Agora/Proposal/validator/unlocking/legal/with 7 stakes/voter: retract votes while voting/stake,1233637333,2786627,12103 -Agora/Proposal/validator/unlocking/legal/with 7 stakes/voter: retract votes while voting/proposal,550025947,1467182,15981 -Agora/Proposal/validator/unlocking/legal/with 7 stakes/voter: retract votes while voting by delegatee/stake,1240464228,2803783,12103 -Agora/Proposal/validator/unlocking/legal/with 7 stakes/voter: retract votes while voting by delegatee/proposal,550025947,1467182,15981 -Agora/Proposal/validator/unlocking/legal/with 7 stakes/voter/creator: retract votes while voting/stake,1307181118,3000841,12185 -Agora/Proposal/validator/unlocking/legal/with 7 stakes/voter/creator: retract votes while voting/proposal,594373775,1596080,16058 -Agora/Proposal/validator/unlocking/legal/with 7 stakes/creator: remove creator lock after voting/stake,1233860264,2794652,12100 -Agora/Proposal/validator/unlocking/legal/with 7 stakes/creator: remove creator lock after voting/proposal,387351397,1003722,15979 -Agora/Proposal/validator/unlocking/legal/with 7 stakes/Voter: remove lock after voting/stake,1234768311,2789031,12108 -Agora/Proposal/validator/unlocking/legal/with 7 stakes/Voter: remove lock after voting/proposal,394619336,1023308,15986 -Agora/Proposal/validator/unlocking/legal/with 9 stakes/voter: retract votes while voting/stake,1591123481,3543091,13448 -Agora/Proposal/validator/unlocking/legal/with 9 stakes/voter: retract votes while voting/proposal,661258847,1757696,17326 -Agora/Proposal/validator/unlocking/legal/with 9 stakes/voter: retract votes while voting by delegatee/stake,1597950376,3560247,13448 -Agora/Proposal/validator/unlocking/legal/with 9 stakes/voter: retract votes while voting by delegatee/proposal,661258847,1757696,17326 -Agora/Proposal/validator/unlocking/legal/with 9 stakes/voter/creator: retract votes while voting/stake,1685679776,3818509,13552 -Agora/Proposal/validator/unlocking/legal/with 9 stakes/voter/creator: retract votes while voting/proposal,718277483,1923422,17425 -Agora/Proposal/validator/unlocking/legal/with 9 stakes/creator: remove creator lock after voting/stake,1591086970,3552722,13443 -Agora/Proposal/validator/unlocking/legal/with 9 stakes/creator: remove creator lock after voting/proposal,455059211,1168972,17322 -Agora/Proposal/validator/unlocking/legal/with 9 stakes/Voter: remove lock after voting/stake,1592254459,3545495,13453 -Agora/Proposal/validator/unlocking/legal/with 9 stakes/Voter: remove lock after voting/proposal,464403704,1194154,17331 -Agora/Proposal/validator/unlocking/legal/with 11 stakes/voter: retract votes while voting/stake,1968256285,4330995,14794 -Agora/Proposal/validator/unlocking/legal/with 11 stakes/voter: retract votes while voting/proposal,772491747,2048210,18672 -Agora/Proposal/validator/unlocking/legal/with 11 stakes/voter: retract votes while voting by delegatee/stake,1975083180,4348151,14794 -Agora/Proposal/validator/unlocking/legal/with 11 stakes/voter: retract votes while voting by delegatee/proposal,772491747,2048210,18672 -Agora/Proposal/validator/unlocking/legal/with 11 stakes/voter/creator: retract votes while voting/stake,2083825090,4667617,14921 -Agora/Proposal/validator/unlocking/legal/with 11 stakes/voter/creator: retract votes while voting/proposal,842181191,2250764,18794 -Agora/Proposal/validator/unlocking/legal/with 11 stakes/creator: remove creator lock after voting/stake,1967960332,4342232,14787 -Agora/Proposal/validator/unlocking/legal/with 11 stakes/creator: remove creator lock after voting/proposal,522767025,1334222,18666 -Agora/Proposal/validator/unlocking/legal/with 11 stakes/Voter: remove lock after voting/stake,1969387263,4333399,14799 -Agora/Proposal/validator/unlocking/legal/with 11 stakes/Voter: remove lock after voting/proposal,534188072,1365000,18677 -Agora/Proposal/validator/unlocking/illegal/with 1 stakes/retract votes while not voting/(negative test)/stake,278493336,704673,8067 -Agora/Proposal/validator/unlocking/illegal/with 1 stakes/retract votes while not voting/(negative test)/stake,279624314,707077,8067 -Agora/Proposal/validator/unlocking/illegal/with 1 stakes/retract votes while not voting/(negative test)/stake,280189803,708279,8067 -Agora/Proposal/validator/unlocking/illegal/with 1 stakes/remove creator too early/(negative test)/proposal,182531488,504366,11949 -Agora/Proposal/validator/unlocking/illegal/with 1 stakes/remove creator too early/(negative test)/proposal,190464307,523106,11949 -Agora/Proposal/validator/unlocking/illegal/with 1 stakes/remove creator too early/(negative test)/proposal,183662466,506770,11949 -Agora/Proposal/validator/unlocking/illegal/with 1 stakes/unlock an irrelevant stake/stake,288706362,739001,8089 -Agora/Proposal/validator/unlocking/illegal/with 1 stakes/creator: retract votes/stake,277406179,708304,8071 -Agora/Proposal/validator/unlocking/illegal/with 1 stakes/change output stake value/proposal,216327247,595640,11942 -Agora/Proposal/validator/unlocking/illegal/with 3 stakes/retract votes while not voting/(negative test)/stake,577039516,1366817,9412 -Agora/Proposal/validator/unlocking/illegal/with 3 stakes/retract votes while not voting/(negative test)/stake,578170494,1369221,9412 -Agora/Proposal/validator/unlocking/illegal/with 3 stakes/retract votes while not voting/(negative test)/stake,578735983,1370423,9412 -Agora/Proposal/validator/unlocking/illegal/with 3 stakes/remove creator too early/(negative test)/proposal,250239302,669616,13292 -Agora/Proposal/validator/unlocking/illegal/with 3 stakes/remove creator too early/(negative test)/proposal,258172121,688356,13292 -Agora/Proposal/validator/unlocking/illegal/with 3 stakes/remove creator too early/(negative test)/proposal,251370280,672020,13292 -Agora/Proposal/validator/unlocking/illegal/with 3 stakes/unlock an irrelevant stake/stake,591812624,1443817,9468 -Agora/Proposal/validator/unlocking/illegal/with 3 stakes/creator: retract votes/stake,557912075,1351726,9426 -Agora/Proposal/validator/unlocking/illegal/with 3 stakes/change output stake value/proposal,327560147,886154,13281 -Agora/Proposal/validator/unlocking/illegal/with 5 stakes/retract votes while not voting/(negative test)/stake,895232352,2060401,10758 -Agora/Proposal/validator/unlocking/illegal/with 5 stakes/retract votes while not voting/(negative test)/stake,896363330,2062805,10758 -Agora/Proposal/validator/unlocking/illegal/with 5 stakes/retract votes while not voting/(negative test)/stake,896928819,2064007,10758 -Agora/Proposal/validator/unlocking/illegal/with 5 stakes/remove creator too early/(negative test)/proposal,317947116,834866,14636 -Agora/Proposal/validator/unlocking/illegal/with 5 stakes/remove creator too early/(negative test)/proposal,325879935,853606,14636 -Agora/Proposal/validator/unlocking/illegal/with 5 stakes/remove creator too early/(negative test)/proposal,319078094,837270,14636 -Agora/Proposal/validator/unlocking/illegal/with 5 stakes/unlock an irrelevant stake/stake,894918886,2148633,10848 -Agora/Proposal/validator/unlocking/illegal/with 5 stakes/creator: retract votes/stake,838417971,1995148,10782 -Agora/Proposal/validator/unlocking/illegal/with 5 stakes/change output stake value/proposal,438793047,1176668,14621 -Agora/Proposal/validator/unlocking/illegal/with 7 stakes/retract votes while not voting/(negative test)/stake,1233071844,2785425,12103 -Agora/Proposal/validator/unlocking/illegal/with 7 stakes/retract votes while not voting/(negative test)/stake,1234202822,2787829,12103 -Agora/Proposal/validator/unlocking/illegal/with 7 stakes/retract votes while not voting/(negative test)/stake,1234768311,2789031,12103 -Agora/Proposal/validator/unlocking/illegal/with 7 stakes/remove creator too early/(negative test)/proposal,385654930,1000116,15979 -Agora/Proposal/validator/unlocking/illegal/with 7 stakes/remove creator too early/(negative test)/proposal,393587749,1018856,15979 -Agora/Proposal/validator/unlocking/illegal/with 7 stakes/remove creator too early/(negative test)/proposal,386785908,1002520,15979 -Agora/Proposal/validator/unlocking/illegal/with 7 stakes/unlock an irrelevant stake/stake,1198025148,2853449,12227 -Agora/Proposal/validator/unlocking/illegal/with 7 stakes/creator: retract votes/stake,1118923867,2638570,12137 -Agora/Proposal/validator/unlocking/illegal/with 7 stakes/change output stake value/proposal,550025947,1467182,15960 -Agora/Proposal/validator/unlocking/illegal/with 9 stakes/retract votes while not voting/(negative test)/stake,1590557992,3541889,13448 -Agora/Proposal/validator/unlocking/illegal/with 9 stakes/retract votes while not voting/(negative test)/stake,1591688970,3544293,13448 -Agora/Proposal/validator/unlocking/illegal/with 9 stakes/retract votes while not voting/(negative test)/stake,1592254459,3545495,13448 -Agora/Proposal/validator/unlocking/illegal/with 9 stakes/remove creator too early/(negative test)/proposal,453362744,1165366,17322 -Agora/Proposal/validator/unlocking/illegal/with 9 stakes/remove creator too early/(negative test)/proposal,461295563,1184106,17322 -Agora/Proposal/validator/unlocking/illegal/with 9 stakes/remove creator too early/(negative test)/proposal,454493722,1167770,17322 -Agora/Proposal/validator/unlocking/illegal/with 9 stakes/unlock an irrelevant stake/stake,1501131410,3558265,13607 -Agora/Proposal/validator/unlocking/illegal/with 9 stakes/creator: retract votes/stake,1399429763,3281992,13492 -Agora/Proposal/validator/unlocking/illegal/with 9 stakes/change output stake value/proposal,661258847,1757696,17299 -Agora/Proposal/validator/unlocking/illegal/with 11 stakes/retract votes while not voting/(negative test)/stake,1967690796,4329793,14794 -Agora/Proposal/validator/unlocking/illegal/with 11 stakes/retract votes while not voting/(negative test)/stake,1968821774,4332197,14794 -Agora/Proposal/validator/unlocking/illegal/with 11 stakes/retract votes while not voting/(negative test)/stake,1969387263,4333399,14794 -Agora/Proposal/validator/unlocking/illegal/with 11 stakes/remove creator too early/(negative test)/proposal,521070558,1330616,18666 -Agora/Proposal/validator/unlocking/illegal/with 11 stakes/remove creator too early/(negative test)/proposal,529003377,1349356,18666 -Agora/Proposal/validator/unlocking/illegal/with 11 stakes/remove creator too early/(negative test)/proposal,522201536,1333020,18666 -Agora/Proposal/validator/unlocking/illegal/with 11 stakes/unlock an irrelevant stake/stake,1804237672,4263081,14987 -Agora/Proposal/validator/unlocking/illegal/with 11 stakes/creator: retract votes/stake,1679935659,3925414,14849 -Agora/Proposal/validator/unlocking/illegal/with 11 stakes/change output stake value/proposal,772491747,2048210,18639 -Agora/AuthorityToken/singleAuthorityTokenBurned/Correct simple,26456223,75851,755 -Agora/AuthorityToken/singleAuthorityTokenBurned/Correct many inputs,51581175,146321,855 -Agora/AuthorityToken/singleAuthorityTokenBurned/Correct even though scripts don't match,26456223,75851,754 -Agora/Treasury/Validator/Positive/Allows for effect changes,42170246,119764,1444 -Agora/Treasury/Validator/Positive/Fails when GAT token name is not script address,42170246,119764,1480 -Agora/AuthorityToken/singleAuthorityTokenBurned/Correct simple,26456223,75851,755 -Agora/AuthorityToken/singleAuthorityTokenBurned/Correct many inputs,51581175,146321,855 -Agora/AuthorityToken/singleAuthorityTokenBurned/Correct even though scripts don't match,26456223,75851,754 -Agora/Governor/policy/totally legal,63319800,170930,2766 -Agora/Governor/validator/mutate/legal,129085947,358459,11531 +Agora/Effects/Treasury Withdrawal Effect/effect/Simple,217066233,586906,3885 +Agora/Effects/Treasury Withdrawal Effect/effect/Simple with multiple treasuries ,308925363,792174,4317 +Agora/Effects/Treasury Withdrawal Effect/effect/Mixed Assets,301366604,790506,4255 +Agora/Effects/Governor Mutation Effect/validator/valid new governor datum/governor validator should pass,133926789,380331,11818 +Agora/Effects/Governor Mutation Effect/validator/valid new governor datum/effect validator should pass,149156621,399941,4851 +Agora/Stake/policy/create/valid/stake owner: pub key,77468330,198844,3625 +Agora/Stake/policy/create/valid/stake owner: script,90607586,237423,3660 +Agora/Stake/validator/destroy/legal/One stake/stake validator,100744620,274835,8167 +Agora/Stake/validator/destroy/legal/One stake/stake policy,29665872,85956,3612 +Agora/Stake/validator/destroy/legal/Multiple stake/stake validator,639511701,1565246,11420 +Agora/Stake/validator/destroy/legal/Multiple stake/stake policy,292337523,820464,6864 +Agora/Stake/validator/destroy/illegal/Destroy locked stakes/stake policy,292337523,820464,6935 +Agora/Stake/validator/destroy/illegal/not authorized by owner/stake policy,292337523,820464,6833 +Agora/Stake/validator/destroy/illegal/not authorized by owner/stake policy,292337523,820464,6864 +Agora/Stake/validator/stakeDepositWithdraw deposit,139642477,368480,8282 +Agora/Stake/validator/stakeDepositWithdraw withdraw,139642477,368480,8274 +Agora/Stake/validator/set delegate/override existing delegate,171170225,438309,8413 +Agora/Stake/validator/set delegate/remove existing delegate,161835229,414921,8343 +Agora/Stake/validator/set delegate/set delegate to something,168741237,431209,8343 +Agora/Proposal/policy (proposal creation)/legal/proposal,33965500,89285,2794 +Agora/Proposal/policy (proposal creation)/legal/governor,286951289,757722,12319 +Agora/Proposal/policy (proposal creation)/legal/stake,300497720,755854,9135 +Agora/Proposal/policy (proposal creation)/illegal/invalid next proposal id/proposal,33965500,89285,2794 +Agora/Proposal/policy (proposal creation)/illegal/invalid next proposal id/stake,300497720,755854,9135 +Agora/Proposal/policy (proposal creation)/illegal/use other's stake/proposal,33965500,89285,2763 +Agora/Proposal/policy (proposal creation)/illegal/use other's stake/governor,286951289,757722,12288 +Agora/Proposal/policy (proposal creation)/illegal/altered stake/proposal,33965500,89285,2794 +Agora/Proposal/policy (proposal creation)/illegal/invalid stake locks/proposal,33965500,89285,2809 +Agora/Proposal/policy (proposal creation)/illegal/invalid stake locks/governor,286951289,757722,12334 +Agora/Proposal/policy (proposal creation)/illegal/has reached maximum proposals limit/proposal,33965500,89285,2818 +Agora/Proposal/policy (proposal creation)/illegal/has reached maximum proposals limit/stake,316856972,802982,9171 +Agora/Proposal/policy (proposal creation)/illegal/loose time range/proposal,33965500,89285,2794 +Agora/Proposal/policy (proposal creation)/illegal/loose time range/stake,300497720,755854,9135 +Agora/Proposal/policy (proposal creation)/illegal/open time range/proposal,33965500,89285,2790 +Agora/Proposal/policy (proposal creation)/illegal/open time range/stake,300497720,755854,9131 +Agora/Proposal/policy (proposal creation)/illegal/invalid proposal status/VotingReady/proposal,33965500,89285,2794 +Agora/Proposal/policy (proposal creation)/illegal/invalid proposal status/VotingReady/stake,300497720,755854,9135 +Agora/Proposal/policy (proposal creation)/illegal/invalid proposal status/Locked/proposal,33965500,89285,2794 +Agora/Proposal/policy (proposal creation)/illegal/invalid proposal status/Locked/stake,300497720,755854,9135 +Agora/Proposal/policy (proposal creation)/illegal/invalid proposal status/Finished/proposal,33965500,89285,2794 +Agora/Proposal/policy (proposal creation)/illegal/invalid proposal status/Finished/stake,300497720,755854,9135 +Agora/Proposal/policy (proposal creation)/illegal/fake SST/proposal,33965500,89285,2701 +Agora/Proposal/policy (proposal creation)/illegal/wrong governor redeemer/stake,300497720,755854,9135 +Agora/Proposal/policy (proposal creation)/illegal/wrong governor redeemer/stake,300497720,755854,9135 +Agora/Proposal/validator/cosignature/legal/proposal,211218458,586864,12534 +Agora/Proposal/validator/cosignature/legal/stake,262516096,688466,8924 +Agora/Proposal/validator/cosignature/illegal/insufficient staked amount/stake,262516096,688466,8924 +Agora/Proposal/validator/cosignature/illegal/proposal locks not updated/proposal,211218458,586864,12527 +Agora/Proposal/validator/cosignature/illegal/duplicate cosigners/stake,270695722,712030,8944 +Agora/Proposal/validator/cosignature/illegal/cosigners not updated/stake,262516096,688466,8890 +Agora/Proposal/validator/cosignature/illegal/cosign after draft/(negative test)/stake,262516096,688466,8924 +Agora/Proposal/validator/cosignature/illegal/cosign after draft/(negative test)/stake,262516096,688466,8924 +Agora/Proposal/validator/cosignature/illegal/cosign after draft/(negative test)/stake,262516096,688466,8924 +Agora/Proposal/validator/voting/legal/different number of stakes/1 stakes/by owner/proposal,236746075,667092,12391 +Agora/Proposal/validator/voting/legal/different number of stakes/1 stakes/by owner/stake,286719534,754693,8797 +Agora/Proposal/validator/voting/legal/different number of stakes/1 stakes/by delegatee/proposal,236746075,667092,12391 +Agora/Proposal/validator/voting/legal/different number of stakes/1 stakes/by delegatee/stake,293546429,771849,8797 +Agora/Proposal/validator/voting/legal/different number of stakes/3 stakes/by owner/proposal,358011461,995038,13625 +Agora/Proposal/validator/voting/legal/different number of stakes/3 stakes/by owner/stake,589841466,1479597,10031 +Agora/Proposal/validator/voting/legal/different number of stakes/3 stakes/by delegatee/proposal,358011461,995038,13625 +Agora/Proposal/validator/voting/legal/different number of stakes/3 stakes/by delegatee/stake,596668361,1496753,10031 +Agora/Proposal/validator/voting/legal/different number of stakes/5 stakes/by owner/proposal,479276847,1322984,14858 +Agora/Proposal/validator/voting/legal/different number of stakes/5 stakes/by owner/stake,892963398,2204501,11264 +Agora/Proposal/validator/voting/legal/different number of stakes/5 stakes/by delegatee/proposal,479276847,1322984,14858 +Agora/Proposal/validator/voting/legal/different number of stakes/5 stakes/by delegatee/stake,899790293,2221657,11264 +Agora/Proposal/validator/voting/legal/different number of stakes/7 stakes/by owner/proposal,600542233,1650930,16091 +Agora/Proposal/validator/voting/legal/different number of stakes/7 stakes/by owner/stake,1196085330,2929405,12497 +Agora/Proposal/validator/voting/legal/different number of stakes/7 stakes/by delegatee/proposal,600542233,1650930,16091 +Agora/Proposal/validator/voting/legal/different number of stakes/7 stakes/by delegatee/stake,1202912225,2946561,12497 +Agora/Proposal/validator/voting/legal/different number of stakes/9 stakes/by owner/proposal,721807619,1978876,17323 +Agora/Proposal/validator/voting/legal/different number of stakes/9 stakes/by owner/stake,1499207262,3654309,13729 +Agora/Proposal/validator/voting/legal/different number of stakes/9 stakes/by delegatee/proposal,721807619,1978876,17323 +Agora/Proposal/validator/voting/legal/different number of stakes/9 stakes/by delegatee/stake,1506034157,3671465,13729 +Agora/Proposal/validator/voting/legal/transparent non-GT tokens/proposal,236746075,667092,12391 +Agora/Proposal/validator/voting/legal/transparent non-GT tokens/stake,286719534,754693,8797 +Agora/Proposal/validator/voting/legal/Delegatee vote with own and delegated stakes in one tx/proposal,476847859,1315884,14788 +Agora/Proposal/validator/voting/legal/Delegatee vote with own and delegated stakes in one tx/stake,902897522,2219654,11194 +Agora/Proposal/validator/voting/illegal/vote for nonexistent outcome/stake,286719534,754693,8805 +Agora/Proposal/validator/voting/illegal/unauthorized tx/proposal,236746075,667092,12391 +Agora/Proposal/validator/voting/illegal/more than one proposals/stake,286719534,754693,8805 +Agora/Proposal/validator/voting/illegal/locks not added/proposal,479276847,1322984,14803 +Agora/Proposal/validator/voting/illegal/attempt to burn stakes/proposal,441096352,1210784,13765 +Agora/Proposal/validator/voting/illegal/insufficient staked amount/stake,286719534,754693,8792 +Agora/Proposal/validator/voting/illegal/insufficient staked amount/stake,892963398,2204501,11242 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Draft to VotingReady/proposal,250538195,701267,13003 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from VotingReady to Locked/proposal,229925297,644252,12766 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Locked to Finished/proposal,243332930,671400,14099 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Locked to Finished/governor,452116200,1203492,13344 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Locked to Finished/authority,96756794,242826,4026 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Draft to VotingReady/proposal,246726905,689039,12724 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from VotingReady to Locked/proposal,226114007,632024,12486 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Locked to Finished/proposal,239521640,659172,13640 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Locked to Finished/governor,449748906,1195986,12978 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Locked to Finished/authority,91691192,229170,3660 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to failed state/from Draft to Finished/proposal,220984544,622913,12758 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to failed state/from VotingReady to Finished/proposal,219256161,612623,12759 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to failed state/from Locked to Finished/proposal,231443065,643435,12759 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to failed state/from Draft to Finished/proposal,217173254,610685,12479 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to failed state/from VotingReady to Finished/proposal,215444871,600395,12480 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to failed state/from Locked to Finished/proposal,227631775,631207,12480 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/advance finished proposals/(negative test)/authority,96756794,242826,4026 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/advance finished proposals/(negative test)/authority,91691192,229170,3660 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/to next state too late/from Locked/governor,452116200,1203492,13344 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/to next state too late/from Locked/authority,96756794,242826,4026 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/to next state too late/from Locked/governor,449748906,1195986,12978 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/to next state too late/from Locked/authority,91691192,229170,3660 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/forget to mint GATs/proposal,239521640,659172,12995 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/mint GATs for wrong validators/proposal,239521640,659172,13640 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/mint GATs for wrong validators/authority,91691192,229170,3660 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/mint GATs with bad token name/proposal,239521640,659172,13672 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/mint GATs with bad token name/authority,91691192,229170,3692 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/wrong GAT datum/proposal,239521640,659172,13634 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/wrong GAT datum/authority,91691192,229170,3654 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/invalid governor output datum/proposal,239521640,659172,13640 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/invalid governor output datum/authority,91691192,229170,3660 +Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/wrong governor redeemer/proposal,239521640,659172,13640 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Draft to VotingReady/proposal,324762915,905569,13919 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from VotingReady to Locked/proposal,307844903,858542,13681 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Locked to Finished/proposal,317557650,875702,15014 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Locked to Finished/governor,493851428,1320724,13954 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Locked to Finished/authority,96756794,242826,4636 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Draft to VotingReady/proposal,317140335,881113,13358 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from VotingReady to Locked/proposal,300222323,834086,13120 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Locked to Finished/proposal,309935070,851246,14275 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Locked to Finished/governor,489729521,1307104,13402 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Locked to Finished/authority,91691192,229170,4084 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to failed state/from Draft to Finished/proposal,295209264,827215,13674 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to failed state/from VotingReady to Finished/proposal,293480881,816925,13675 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to failed state/from Locked to Finished/proposal,305667785,847737,13675 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to failed state/from Draft to Finished/proposal,287586684,802759,13113 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to failed state/from VotingReady to Finished/proposal,285858301,792469,13114 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to failed state/from Locked to Finished/proposal,298045205,823281,13114 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/advance finished proposals/(negative test)/authority,96756794,242826,4636 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/advance finished proposals/(negative test)/authority,91691192,229170,4084 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/to next state too late/from Locked/governor,493851428,1320724,13954 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/to next state too late/from Locked/authority,96756794,242826,4636 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/to next state too late/from Locked/governor,489729521,1307104,13402 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/to next state too late/from Locked/authority,91691192,229170,4084 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/forget to mint GATs/proposal,309935070,851246,13629 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/mint GATs for wrong validators/proposal,309935070,851246,14275 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/mint GATs for wrong validators/authority,91691192,229170,4084 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/mint GATs with bad token name/proposal,309935070,851246,14307 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/mint GATs with bad token name/authority,91691192,229170,4116 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/wrong GAT datum/proposal,309935070,851246,14269 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/wrong GAT datum/authority,91691192,229170,4078 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/invalid governor output datum/proposal,309935070,851246,14275 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/invalid governor output datum/authority,91691192,229170,4084 +Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/wrong governor redeemer/proposal,309935070,851246,14275 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Draft to VotingReady/proposal,547437075,1518475,16666 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from VotingReady to Locked/proposal,541603721,1501412,16428 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Locked to Finished/proposal,540231810,1488608,17761 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Locked to Finished/governor,619057112,1672420,15785 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Locked to Finished/authority,96756794,242826,6467 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Draft to VotingReady/proposal,528380625,1457335,15265 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from VotingReady to Locked/proposal,522547271,1440272,15027 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Locked to Finished/proposal,521175360,1427468,16182 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Locked to Finished/governor,609671366,1640458,14673 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Locked to Finished/authority,91691192,229170,5355 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to failed state/from Draft to Finished/proposal,517883424,1440121,16421 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to failed state/from VotingReady to Finished/proposal,516155041,1429831,16422 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to failed state/from Locked to Finished/proposal,528341945,1460643,16422 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to failed state/from Draft to Finished/proposal,498826974,1378981,15020 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to failed state/from VotingReady to Finished/proposal,497098591,1368691,15021 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to failed state/from Locked to Finished/proposal,509285495,1399503,15021 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/advance finished proposals/(negative test)/authority,96756794,242826,6467 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/advance finished proposals/(negative test)/authority,91691192,229170,5355 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/to next state too late/from Locked/governor,619057112,1672420,15785 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/to next state too late/from Locked/authority,96756794,242826,6467 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/to next state too late/from Locked/governor,609671366,1640458,14673 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/to next state too late/from Locked/authority,91691192,229170,5355 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/forget to mint GATs/proposal,521175360,1427468,15536 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/mint GATs for wrong validators/proposal,521175360,1427468,16182 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/mint GATs for wrong validators/authority,91691192,229170,5355 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/mint GATs with bad token name/proposal,521175360,1427468,16214 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/mint GATs with bad token name/authority,91691192,229170,5387 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/wrong GAT datum/proposal,521175360,1427468,16176 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/wrong GAT datum/authority,91691192,229170,5349 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/invalid governor output datum/proposal,521175360,1427468,16182 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/invalid governor output datum/authority,91691192,229170,5355 +Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/wrong governor redeemer/proposal,521175360,1427468,16182 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Draft to VotingReady/proposal,430665389,1180363,14504 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from VotingReady to Locked/proposal,260276017,727980,13176 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Locked to Finished/proposal,273683650,755128,14509 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Locked to Finished/governor,466989496,1245356,13617 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Locked to Finished/authority,96756794,242826,4299 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Draft to VotingReady/proposal,426854099,1168135,14223 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from VotingReady to Locked/proposal,256464727,715752,12895 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Locked to Finished/proposal,269872360,742900,14049 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Locked to Finished/governor,464622202,1237850,13251 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Locked to Finished/authority,91691192,229170,3933 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to failed state/from Draft to Finished/proposal,251335264,706641,13169 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to failed state/from VotingReady to Finished/proposal,249606881,696351,13170 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to failed state/from Locked to Finished/proposal,261793785,727163,13170 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to failed state/from Draft to Finished/proposal,247523974,694413,12888 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to failed state/from VotingReady to Finished/proposal,245795591,684123,12889 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to failed state/from Locked to Finished/proposal,257982495,714935,12889 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/advance finished proposals/(negative test)/authority,96756794,242826,4299 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/advance finished proposals/(negative test)/authority,91691192,229170,3933 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/to next state too late/from Locked/governor,466989496,1245356,13617 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/to next state too late/from Locked/authority,96756794,242826,4299 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/to next state too late/from Locked/governor,464622202,1237850,13251 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/to next state too late/from Locked/authority,91691192,229170,3933 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/forget to mint GATs/proposal,269872360,742900,13404 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/mint GATs for wrong validators/proposal,269872360,742900,14049 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/mint GATs for wrong validators/authority,91691192,229170,3933 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/mint GATs with bad token name/proposal,269872360,742900,14081 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/mint GATs with bad token name/authority,91691192,229170,3965 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/wrong GAT datum/proposal,269872360,742900,14043 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/wrong GAT datum/authority,91691192,229170,3927 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/invalid governor output datum/proposal,269872360,742900,14049 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/invalid governor output datum/authority,91691192,229170,3933 +Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/wrong governor redeemer/proposal,269872360,742900,14049 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Draft to VotingReady/proposal,504890109,1384665,15419 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from VotingReady to Locked/proposal,338195623,942270,14091 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Locked to Finished/proposal,347908370,959430,15424 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Locked to Finished/governor,508724724,1362588,14227 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Locked to Finished/authority,96756794,242826,4909 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Draft to VotingReady/proposal,497267529,1360209,14859 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from VotingReady to Locked/proposal,330573043,917814,13531 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Locked to Finished/proposal,340285790,934974,14685 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Locked to Finished/governor,504602817,1348968,13675 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Locked to Finished/authority,91691192,229170,4357 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to failed state/from Draft to Finished/proposal,325559984,910943,14084 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to failed state/from VotingReady to Finished/proposal,323831601,900653,14085 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to failed state/from Locked to Finished/proposal,336018505,931465,14085 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to failed state/from Draft to Finished/proposal,317937404,886487,13523 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to failed state/from VotingReady to Finished/proposal,316209021,876197,13524 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to failed state/from Locked to Finished/proposal,328395925,907009,13524 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/advance finished proposals/(negative test)/authority,96756794,242826,4909 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/advance finished proposals/(negative test)/authority,91691192,229170,4357 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/to next state too late/from Locked/governor,508724724,1362588,14227 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/to next state too late/from Locked/authority,96756794,242826,4909 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/to next state too late/from Locked/governor,504602817,1348968,13675 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/to next state too late/from Locked/authority,91691192,229170,4357 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/forget to mint GATs/proposal,340285790,934974,14039 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/mint GATs for wrong validators/proposal,340285790,934974,14685 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/mint GATs for wrong validators/authority,91691192,229170,4357 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/mint GATs with bad token name/proposal,340285790,934974,14717 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/mint GATs with bad token name/authority,91691192,229170,4389 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/wrong GAT datum/proposal,340285790,934974,14679 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/wrong GAT datum/authority,91691192,229170,4351 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/invalid governor output datum/proposal,340285790,934974,14685 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/invalid governor output datum/authority,91691192,229170,4357 +Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/wrong governor redeemer/proposal,340285790,934974,14685 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Draft to VotingReady/proposal,727564269,1997571,18165 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from VotingReady to Locked/proposal,571954441,1585140,16837 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Locked to Finished/proposal,570582530,1572336,18170 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Locked to Finished/governor,633930408,1714284,16058 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Locked to Finished/authority,96756794,242826,6740 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Draft to VotingReady/proposal,708507819,1936431,16765 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from VotingReady to Locked/proposal,552897991,1524000,15437 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Locked to Finished/proposal,551526080,1511196,16592 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Locked to Finished/governor,624544662,1682322,14946 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Locked to Finished/authority,91691192,229170,5628 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to failed state/from Draft to Finished/proposal,548234144,1523849,16830 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to failed state/from VotingReady to Finished/proposal,546505761,1513559,16831 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to failed state/from Locked to Finished/proposal,558692665,1544371,16831 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to failed state/from Draft to Finished/proposal,529177694,1462709,15429 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to failed state/from VotingReady to Finished/proposal,527449311,1452419,15430 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to failed state/from Locked to Finished/proposal,539636215,1483231,15430 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/advance finished proposals/(negative test)/authority,96756794,242826,6740 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/advance finished proposals/(negative test)/authority,91691192,229170,5628 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/to next state too late/from Locked/governor,633930408,1714284,16058 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/to next state too late/from Locked/authority,96756794,242826,6740 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/to next state too late/from Locked/governor,624544662,1682322,14946 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/to next state too late/from Locked/authority,91691192,229170,5628 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/forget to mint GATs/proposal,551526080,1511196,15946 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/mint GATs for wrong validators/proposal,551526080,1511196,16592 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/mint GATs for wrong validators/authority,91691192,229170,5628 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/mint GATs with bad token name/proposal,551526080,1511196,16624 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/mint GATs with bad token name/authority,91691192,229170,5660 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/wrong GAT datum/proposal,551526080,1511196,16586 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/wrong GAT datum/authority,91691192,229170,5622 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/invalid governor output datum/proposal,551526080,1511196,16592 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/invalid governor output datum/authority,91691192,229170,5628 +Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/wrong governor redeemer/proposal,551526080,1511196,16592 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Draft to VotingReady/proposal,670987825,1824924,16380 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from VotingReady to Locked/proposal,298214417,832640,13687 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Locked to Finished/proposal,311622050,859788,15020 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Locked to Finished/governor,485581116,1297686,13958 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Locked to Finished/authority,96756794,242826,4640 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Draft to VotingReady/proposal,667176535,1812696,16101 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from VotingReady to Locked/proposal,294403127,820412,13407 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Locked to Finished/proposal,307810760,847560,14562 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Locked to Finished/governor,483213822,1290180,13593 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Locked to Finished/authority,91691192,229170,4275 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to failed state/from Draft to Finished/proposal,289273664,811301,13680 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to failed state/from VotingReady to Finished/proposal,287545281,801011,13681 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to failed state/from Locked to Finished/proposal,299732185,831823,13681 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to failed state/from Draft to Finished/proposal,285462374,799073,13400 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to failed state/from VotingReady to Finished/proposal,283733991,788783,13401 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to failed state/from Locked to Finished/proposal,295920895,819595,13401 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/advance finished proposals/(negative test)/authority,96756794,242826,4640 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/advance finished proposals/(negative test)/authority,91691192,229170,4275 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/to next state too late/from Locked/governor,485581116,1297686,13958 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/to next state too late/from Locked/authority,96756794,242826,4640 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/to next state too late/from Locked/governor,483213822,1290180,13593 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/to next state too late/from Locked/authority,91691192,229170,4275 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/forget to mint GATs/proposal,307810760,847560,13916 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/mint GATs for wrong validators/proposal,307810760,847560,14562 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/mint GATs for wrong validators/authority,91691192,229170,4275 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/mint GATs with bad token name/proposal,307810760,847560,14594 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/mint GATs with bad token name/authority,91691192,229170,4307 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/wrong GAT datum/proposal,307810760,847560,14556 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/wrong GAT datum/authority,91691192,229170,4269 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/invalid governor output datum/proposal,307810760,847560,14562 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/invalid governor output datum/authority,91691192,229170,4275 +Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/wrong governor redeemer/proposal,307810760,847560,14562 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Draft to VotingReady/proposal,745212545,2029226,17296 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from VotingReady to Locked/proposal,376134023,1046930,14602 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Locked to Finished/proposal,385846770,1064090,15936 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Locked to Finished/governor,527316344,1414918,14569 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Locked to Finished/authority,96756794,242826,5250 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Draft to VotingReady/proposal,737589965,2004770,16736 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from VotingReady to Locked/proposal,368511443,1022474,14043 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Locked to Finished/proposal,378224190,1039634,15197 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Locked to Finished/governor,523194437,1401298,14016 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Locked to Finished/authority,91691192,229170,4698 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to failed state/from Draft to Finished/proposal,363498384,1015603,14595 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to failed state/from VotingReady to Finished/proposal,361770001,1005313,14596 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to failed state/from Locked to Finished/proposal,373956905,1036125,14596 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to failed state/from Draft to Finished/proposal,355875804,991147,14036 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to failed state/from VotingReady to Finished/proposal,354147421,980857,14037 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to failed state/from Locked to Finished/proposal,366334325,1011669,14037 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/advance finished proposals/(negative test)/authority,96756794,242826,5250 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/advance finished proposals/(negative test)/authority,91691192,229170,4698 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/to next state too late/from Locked/governor,527316344,1414918,14569 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/to next state too late/from Locked/authority,96756794,242826,5250 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/to next state too late/from Locked/governor,523194437,1401298,14016 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/to next state too late/from Locked/authority,91691192,229170,4698 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/forget to mint GATs/proposal,378224190,1039634,14552 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/mint GATs for wrong validators/proposal,378224190,1039634,15197 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/mint GATs for wrong validators/authority,91691192,229170,4698 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/mint GATs with bad token name/proposal,378224190,1039634,15229 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/mint GATs with bad token name/authority,91691192,229170,4730 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/wrong GAT datum/proposal,378224190,1039634,15191 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/wrong GAT datum/authority,91691192,229170,4692 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/invalid governor output datum/proposal,378224190,1039634,15197 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/invalid governor output datum/authority,91691192,229170,4698 +Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/wrong governor redeemer/proposal,378224190,1039634,15197 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Draft to VotingReady/proposal,967886705,2642132,20043 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from VotingReady to Locked/proposal,609892841,1689800,17349 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Locked to Finished/proposal,608520930,1676996,18683 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Locked to Finished/governor,652522028,1766614,16400 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Locked to Finished/authority,96756794,242826,7082 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Draft to VotingReady/proposal,948830255,2580992,18642 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from VotingReady to Locked/proposal,590836391,1628660,15949 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Locked to Finished/proposal,589464480,1615856,17103 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Locked to Finished/governor,643136282,1734652,15287 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Locked to Finished/authority,91691192,229170,5969 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to failed state/from Draft to Finished/proposal,586172544,1628509,17342 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to failed state/from VotingReady to Finished/proposal,584444161,1618219,17343 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to failed state/from Locked to Finished/proposal,596631065,1649031,17343 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to failed state/from Draft to Finished/proposal,567116094,1567369,15942 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to failed state/from VotingReady to Finished/proposal,565387711,1557079,15943 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to failed state/from Locked to Finished/proposal,577574615,1587891,15943 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/advance finished proposals/(negative test)/authority,96756794,242826,7082 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/advance finished proposals/(negative test)/authority,91691192,229170,5969 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/to next state too late/from Locked/governor,652522028,1766614,16400 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/to next state too late/from Locked/authority,96756794,242826,7082 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/to next state too late/from Locked/governor,643136282,1734652,15287 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/to next state too late/from Locked/authority,91691192,229170,5969 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/forget to mint GATs/proposal,589464480,1615856,16458 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/mint GATs for wrong validators/proposal,589464480,1615856,17103 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/mint GATs for wrong validators/authority,91691192,229170,5969 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/mint GATs with bad token name/proposal,589464480,1615856,17135 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/mint GATs with bad token name/authority,91691192,229170,6001 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/wrong GAT datum/proposal,589464480,1615856,17097 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/wrong GAT datum/authority,91691192,229170,5963 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/invalid governor output datum/proposal,589464480,1615856,17103 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/invalid governor output datum/authority,91691192,229170,5969 +Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/wrong governor redeemer/proposal,589464480,1615856,17103 +Agora/Proposal/validator/unlocking/legal/with 1 stakes/voter: retract votes while voting/stake,293224159,762702,9027 +Agora/Proposal/validator/unlocking/legal/with 1 stakes/voter: retract votes while voting/proposal,250729998,700174,12627 +Agora/Proposal/validator/unlocking/legal/with 1 stakes/voter: retract votes while voting by delegatee/stake,300051054,779858,9027 +Agora/Proposal/validator/unlocking/legal/with 1 stakes/voter: retract votes while voting by delegatee/proposal,250729998,700174,12627 +Agora/Proposal/validator/unlocking/legal/with 1 stakes/voter/creator: retract votes while voting/stake,305673493,792301,9039 +Agora/Proposal/validator/unlocking/legal/with 1 stakes/voter/creator: retract votes while voting/proposal,261958222,733268,12633 +Agora/Proposal/validator/unlocking/legal/with 1 stakes/creator: remove creator lock after voting/stake,286343529,742697,9020 +Agora/Proposal/validator/unlocking/legal/with 1 stakes/creator: remove creator lock after voting/proposal,194627614,541712,12624 +Agora/Proposal/validator/unlocking/legal/with 1 stakes/Voter: remove lock after voting/stake,290948981,754990,9032 +Agora/Proposal/validator/unlocking/legal/with 1 stakes/Voter: remove lock after voting/proposal,196700632,547308,12632 +Agora/Proposal/validator/unlocking/legal/with 3 stakes/voter: retract votes while voting/stake,582113987,1442022,10403 +Agora/Proposal/validator/unlocking/legal/with 3 stakes/voter: retract votes while voting/proposal,404537296,1122004,14003 +Agora/Proposal/validator/unlocking/legal/with 3 stakes/voter: retract votes while voting by delegatee/stake,588940882,1459178,10403 +Agora/Proposal/validator/unlocking/legal/with 3 stakes/voter: retract votes while voting by delegatee/proposal,404537296,1122004,14003 +Agora/Proposal/validator/unlocking/legal/with 3 stakes/voter/creator: retract votes while voting/stake,634196981,1554399,10427 +Agora/Proposal/validator/unlocking/legal/with 3 stakes/voter/creator: retract votes while voting/proposal,438221968,1221286,14021 +Agora/Proposal/validator/unlocking/legal/with 3 stakes/creator: remove creator lock after voting/stake,562666017,1388031,10379 +Agora/Proposal/validator/unlocking/legal/with 3 stakes/creator: remove creator lock after voting/proposal,264253492,713018,13983 +Agora/Proposal/validator/unlocking/legal/with 3 stakes/Voter: remove lock after voting/stake,576482373,1424910,10408 +Agora/Proposal/validator/unlocking/legal/with 3 stakes/Voter: remove lock after voting/proposal,270472546,729806,14008 +Agora/Proposal/validator/unlocking/legal/with 5 stakes/voter: retract votes while voting/stake,871003815,2121342,11778 +Agora/Proposal/validator/unlocking/legal/with 5 stakes/voter: retract votes while voting/proposal,558344594,1543834,15378 +Agora/Proposal/validator/unlocking/legal/with 5 stakes/voter: retract votes while voting by delegatee/stake,877830710,2138498,11778 +Agora/Proposal/validator/unlocking/legal/with 5 stakes/voter: retract votes while voting by delegatee/proposal,558344594,1543834,15378 +Agora/Proposal/validator/unlocking/legal/with 5 stakes/voter/creator: retract votes while voting/stake,982367125,2347937,11814 +Agora/Proposal/validator/unlocking/legal/with 5 stakes/voter/creator: retract votes while voting/proposal,614485714,1709304,15408 +Agora/Proposal/validator/unlocking/legal/with 5 stakes/creator: remove creator lock after voting/stake,838988505,2033365,11739 +Agora/Proposal/validator/unlocking/legal/with 5 stakes/creator: remove creator lock after voting/proposal,333879370,884324,15343 +Agora/Proposal/validator/unlocking/legal/with 5 stakes/Voter: remove lock after voting/stake,862015765,2094830,11783 +Agora/Proposal/validator/unlocking/legal/with 5 stakes/Voter: remove lock after voting/proposal,344244460,912304,15383 +Agora/Proposal/validator/unlocking/legal/with 7 stakes/voter: retract votes while voting/stake,1159893643,2800662,13153 +Agora/Proposal/validator/unlocking/legal/with 7 stakes/voter: retract votes while voting/proposal,712151892,1965664,16753 +Agora/Proposal/validator/unlocking/legal/with 7 stakes/voter: retract votes while voting by delegatee/stake,1166720538,2817818,13153 +Agora/Proposal/validator/unlocking/legal/with 7 stakes/voter: retract votes while voting by delegatee/proposal,712151892,1965664,16753 +Agora/Proposal/validator/unlocking/legal/with 7 stakes/voter/creator: retract votes while voting/stake,1350183925,3172915,13201 +Agora/Proposal/validator/unlocking/legal/with 7 stakes/voter/creator: retract votes while voting/proposal,790749460,2197322,16795 +Agora/Proposal/validator/unlocking/legal/with 7 stakes/creator: remove creator lock after voting/stake,1115310993,2678699,13098 +Agora/Proposal/validator/unlocking/legal/with 7 stakes/creator: remove creator lock after voting/proposal,403505248,1055630,16702 +Agora/Proposal/validator/unlocking/legal/with 7 stakes/Voter: remove lock after voting/stake,1147549157,2764750,13158 +Agora/Proposal/validator/unlocking/legal/with 7 stakes/Voter: remove lock after voting/proposal,418016374,1094802,16758 +Agora/Proposal/validator/unlocking/legal/with 9 stakes/voter: retract votes while voting/stake,1448783471,3479982,14529 +Agora/Proposal/validator/unlocking/legal/with 9 stakes/voter: retract votes while voting/proposal,865959190,2387494,18129 +Agora/Proposal/validator/unlocking/legal/with 9 stakes/voter: retract votes while voting by delegatee/stake,1455610366,3497138,14529 +Agora/Proposal/validator/unlocking/legal/with 9 stakes/voter: retract votes while voting by delegatee/proposal,865959190,2387494,18129 +Agora/Proposal/validator/unlocking/legal/with 9 stakes/voter/creator: retract votes while voting/stake,1737647381,4029333,14589 +Agora/Proposal/validator/unlocking/legal/with 9 stakes/voter/creator: retract votes while voting/proposal,967013206,2685340,18183 +Agora/Proposal/validator/unlocking/legal/with 9 stakes/creator: remove creator lock after voting/stake,1391633481,3324033,14457 +Agora/Proposal/validator/unlocking/legal/with 9 stakes/creator: remove creator lock after voting/proposal,473131126,1226936,18061 +Agora/Proposal/validator/unlocking/legal/with 9 stakes/Voter: remove lock after voting/stake,1433082549,3434670,14534 +Agora/Proposal/validator/unlocking/legal/with 9 stakes/Voter: remove lock after voting/proposal,491788288,1277300,18134 +Agora/Proposal/validator/unlocking/legal/with 11 stakes/voter: retract votes while voting/stake,1737673299,4159302,15905 +Agora/Proposal/validator/unlocking/legal/with 11 stakes/voter: retract votes while voting/proposal,1019766488,2809324,19505 +Agora/Proposal/validator/unlocking/legal/with 11 stakes/voter: retract votes while voting by delegatee/stake,1744500194,4176458,15905 +Agora/Proposal/validator/unlocking/legal/with 11 stakes/voter: retract votes while voting by delegatee/proposal,1019766488,2809324,19505 +Agora/Proposal/validator/unlocking/legal/with 11 stakes/voter/creator: retract votes while voting/stake,2144757493,4917191,15977 +Agora/Proposal/validator/unlocking/legal/with 11 stakes/voter/creator: retract votes while voting/proposal,1143276952,3173358,19571 +Agora/Proposal/validator/unlocking/legal/with 11 stakes/creator: remove creator lock after voting/stake,1667955969,3969367,15818 +Agora/Proposal/validator/unlocking/legal/with 11 stakes/creator: remove creator lock after voting/proposal,542757004,1398242,19422 +Agora/Proposal/validator/unlocking/legal/with 11 stakes/Voter: remove lock after voting/stake,1718615941,4104590,15910 +Agora/Proposal/validator/unlocking/legal/with 11 stakes/Voter: remove lock after voting/proposal,565560202,1459798,19510 +Agora/Proposal/validator/unlocking/illegal/with 1 stakes/retract votes while not voting/(negative test)/stake,292658670,761500,9027 +Agora/Proposal/validator/unlocking/illegal/with 1 stakes/retract votes while not voting/(negative test)/stake,293789648,763904,9027 +Agora/Proposal/validator/unlocking/illegal/with 1 stakes/retract votes while not voting/(negative test)/stake,290948981,754990,9027 +Agora/Proposal/validator/unlocking/illegal/with 1 stakes/remove creator too early/(negative test)/proposal,192931147,538106,12624 +Agora/Proposal/validator/unlocking/illegal/with 1 stakes/remove creator too early/(negative test)/proposal,201089148,557678,12624 +Agora/Proposal/validator/unlocking/illegal/with 1 stakes/remove creator too early/(negative test)/proposal,194062125,540510,12624 +Agora/Proposal/validator/unlocking/illegal/with 1 stakes/unlock an irrelevant stake/stake,294561760,762166,9028 +Agora/Proposal/validator/unlocking/illegal/with 1 stakes/creator: retract votes/stake,287523038,741355,9008 +Agora/Proposal/validator/unlocking/illegal/with 1 stakes/change output stake value/proposal,250729998,700174,12624 +Agora/Proposal/validator/unlocking/illegal/with 1 stakes/retract votes in cooldown/proposal,261958222,733268,12633 +Agora/Proposal/validator/unlocking/illegal/with 3 stakes/retract votes while not voting/(negative test)/stake,581548498,1440820,10403 +Agora/Proposal/validator/unlocking/illegal/with 3 stakes/retract votes while not voting/(negative test)/stake,582679476,1443224,10403 +Agora/Proposal/validator/unlocking/illegal/with 3 stakes/retract votes while not voting/(negative test)/stake,576482373,1424910,10403 +Agora/Proposal/validator/unlocking/illegal/with 3 stakes/remove creator too early/(negative test)/proposal,262557025,709412,13983 +Agora/Proposal/validator/unlocking/illegal/with 3 stakes/remove creator too early/(negative test)/proposal,270715026,728984,13983 +Agora/Proposal/validator/unlocking/illegal/with 3 stakes/remove creator too early/(negative test)/proposal,263688003,711816,13983 +Agora/Proposal/validator/unlocking/illegal/with 3 stakes/unlock an irrelevant stake/stake,600861782,1463994,10393 +Agora/Proposal/validator/unlocking/illegal/with 3 stakes/creator: retract votes/stake,579745616,1401561,10353 +Agora/Proposal/validator/unlocking/illegal/with 3 stakes/change output stake value/proposal,404537296,1122004,13993 +Agora/Proposal/validator/unlocking/illegal/with 3 stakes/retract votes in cooldown/proposal,438221968,1221286,14021 +Agora/Proposal/validator/unlocking/illegal/with 5 stakes/retract votes while not voting/(negative test)/stake,870438326,2120140,11778 +Agora/Proposal/validator/unlocking/illegal/with 5 stakes/retract votes while not voting/(negative test)/stake,871569304,2122544,11778 +Agora/Proposal/validator/unlocking/illegal/with 5 stakes/retract votes while not voting/(negative test)/stake,862015765,2094830,11778 +Agora/Proposal/validator/unlocking/illegal/with 5 stakes/remove creator too early/(negative test)/proposal,332182903,880718,15343 +Agora/Proposal/validator/unlocking/illegal/with 5 stakes/remove creator too early/(negative test)/proposal,340340904,900290,15343 +Agora/Proposal/validator/unlocking/illegal/with 5 stakes/remove creator too early/(negative test)/proposal,333313881,883122,15343 +Agora/Proposal/validator/unlocking/illegal/with 5 stakes/unlock an irrelevant stake/stake,926808460,2197262,11759 +Agora/Proposal/validator/unlocking/illegal/with 5 stakes/creator: retract votes/stake,891614850,2093207,11699 +Agora/Proposal/validator/unlocking/illegal/with 5 stakes/change output stake value/proposal,558344594,1543834,15363 +Agora/Proposal/validator/unlocking/illegal/with 5 stakes/retract votes in cooldown/proposal,614485714,1709304,15408 +Agora/Proposal/validator/unlocking/illegal/with 7 stakes/retract votes while not voting/(negative test)/stake,1159328154,2799460,13153 +Agora/Proposal/validator/unlocking/illegal/with 7 stakes/retract votes while not voting/(negative test)/stake,1160459132,2801864,13153 +Agora/Proposal/validator/unlocking/illegal/with 7 stakes/retract votes while not voting/(negative test)/stake,1147549157,2764750,13153 +Agora/Proposal/validator/unlocking/illegal/with 7 stakes/remove creator too early/(negative test)/proposal,401808781,1052024,16702 +Agora/Proposal/validator/unlocking/illegal/with 7 stakes/remove creator too early/(negative test)/proposal,409966782,1071596,16702 +Agora/Proposal/validator/unlocking/illegal/with 7 stakes/remove creator too early/(negative test)/proposal,402939759,1054428,16702 +Agora/Proposal/validator/unlocking/illegal/with 7 stakes/unlock an irrelevant stake/stake,1272401794,2961970,13124 +Agora/Proposal/validator/unlocking/illegal/with 7 stakes/creator: retract votes/stake,1223130740,2816293,13044 +Agora/Proposal/validator/unlocking/illegal/with 7 stakes/change output stake value/proposal,712151892,1965664,16732 +Agora/Proposal/validator/unlocking/illegal/with 7 stakes/retract votes in cooldown/proposal,790749460,2197322,16795 +Agora/Proposal/validator/unlocking/illegal/with 9 stakes/retract votes while not voting/(negative test)/stake,1448217982,3478780,14529 +Agora/Proposal/validator/unlocking/illegal/with 9 stakes/retract votes while not voting/(negative test)/stake,1449348960,3481184,14529 +Agora/Proposal/validator/unlocking/illegal/with 9 stakes/retract votes while not voting/(negative test)/stake,1433082549,3434670,14529 +Agora/Proposal/validator/unlocking/illegal/with 9 stakes/remove creator too early/(negative test)/proposal,471434659,1223330,18061 +Agora/Proposal/validator/unlocking/illegal/with 9 stakes/remove creator too early/(negative test)/proposal,479592660,1242902,18061 +Agora/Proposal/validator/unlocking/illegal/with 9 stakes/remove creator too early/(negative test)/proposal,472565637,1225734,18061 +Agora/Proposal/validator/unlocking/illegal/with 9 stakes/unlock an irrelevant stake/stake,1637641784,3758118,14489 +Agora/Proposal/validator/unlocking/illegal/with 9 stakes/creator: retract votes/stake,1574293286,3570819,14389 +Agora/Proposal/validator/unlocking/illegal/with 9 stakes/change output stake value/proposal,865959190,2387494,18102 +Agora/Proposal/validator/unlocking/illegal/with 9 stakes/retract votes in cooldown/proposal,967013206,2685340,18183 +Agora/Proposal/validator/unlocking/illegal/with 11 stakes/retract votes while not voting/(negative test)/stake,1737107810,4158100,15905 +Agora/Proposal/validator/unlocking/illegal/with 11 stakes/retract votes while not voting/(negative test)/stake,1738238788,4160504,15905 +Agora/Proposal/validator/unlocking/illegal/with 11 stakes/retract votes while not voting/(negative test)/stake,1718615941,4104590,15905 +Agora/Proposal/validator/unlocking/illegal/with 11 stakes/remove creator too early/(negative test)/proposal,541060537,1394636,19422 +Agora/Proposal/validator/unlocking/illegal/with 11 stakes/remove creator too early/(negative test)/proposal,549218538,1414208,19422 +Agora/Proposal/validator/unlocking/illegal/with 11 stakes/remove creator too early/(negative test)/proposal,542191515,1397040,19422 +Agora/Proposal/validator/unlocking/illegal/with 11 stakes/unlock an irrelevant stake/stake,2022528430,4585706,15856 +Agora/Proposal/validator/unlocking/illegal/with 11 stakes/creator: retract votes/stake,1945102488,4356785,15735 +Agora/Proposal/validator/unlocking/illegal/with 11 stakes/change output stake value/proposal,1019766488,2809324,19472 +Agora/Proposal/validator/unlocking/illegal/with 11 stakes/retract votes in cooldown/proposal,1143276952,3173358,19571 +Agora/AuthorityToken/singleAuthorityTokenBurned/Correct simple,26525223,76151,758 +Agora/AuthorityToken/singleAuthorityTokenBurned/Correct many inputs,51650175,146621,858 +Agora/AuthorityToken/singleAuthorityTokenBurned/Correct even though scripts don't match,26525223,76151,757 +Agora/Treasury/Validator/Positive/Allows for effect changes,42239246,120064,1447 +Agora/Treasury/Validator/Positive/Fails when GAT token name is not script address,42239246,120064,1483 +Agora/AuthorityToken/singleAuthorityTokenBurned/Correct simple,26525223,76151,758 +Agora/AuthorityToken/singleAuthorityTokenBurned/Correct many inputs,51650175,146621,858 +Agora/AuthorityToken/singleAuthorityTokenBurned/Correct even though scripts don't match,26525223,76151,757 +Agora/Governor/policy/totally legal,67458764,182122,2868 +Agora/Governor/validator/mutate/legal,138825121,389627,11624 diff --git a/flake.lock b/flake.lock index 579241a..7162c0d 100644 --- a/flake.lock +++ b/flake.lock @@ -559,11 +559,11 @@ "nixpkgs-2205": "nixpkgs-2205" }, "locked": { - "lastModified": 1660580223, - "narHash": "sha256-r1i92rrUjSBdnQZpHLxeCAtVGMHYqKQHm05mzddIte8=", + "lastModified": 1666695559, + "narHash": "sha256-v8DcNma4hAgLCbPHpsxNYzeMURfbxh20VXfFzUED6bs=", "owner": "Liqwid-Labs", "repo": "liqwid-nix", - "rev": "fa1eeba35b37ac2551a00798dffdf053879699c3", + "rev": "7add1f24e9360e96b2bab4a1fc7929d4fa649439", "type": "github" }, "original": { @@ -631,14 +631,15 @@ }, "liqwid-nix_6": { "inputs": { - "nixpkgs": "nixpkgs_9" + "nixpkgs": "nixpkgs_9", + "nixpkgs-2205": "nixpkgs-2205_5" }, "locked": { - "lastModified": 1659383708, - "narHash": "sha256-eenTO5t4ocK7VzorMUdUyKUoup976cCu5dJcVjebY8E=", + "lastModified": 1666695559, + "narHash": "sha256-v8DcNma4hAgLCbPHpsxNYzeMURfbxh20VXfFzUED6bs=", "owner": "Liqwid-Labs", "repo": "liqwid-nix", - "rev": "c261df76dc31b3dc5dfde7030420e0a6be73f615", + "rev": "7add1f24e9360e96b2bab4a1fc7929d4fa649439", "type": "github" }, "original": { @@ -691,11 +692,11 @@ ] }, "locked": { - "lastModified": 1666735011, - "narHash": "sha256-ugpT7IHlga+fq8+CTYW+MZa4OT4f6Xp+UaWSbbJUTgM=", + "lastModified": 1668121695, + "narHash": "sha256-2ltW7mvn14zm9f67OmxXIPJHAXR6vxBdN/6Q6nRh7a8=", "owner": "Liqwid-Labs", "repo": "liqwid-plutarch-extra", - "rev": "a5be78478418aff2312787860f4736837f24494e", + "rev": "0cb63aa7d4fd2006cf590edc7fca0f3fcdb71a55", "type": "github" }, "original": { @@ -952,6 +953,38 @@ "type": "github" } }, + "nixpkgs-2205_5": { + "locked": { + "lastModified": 1660033036, + "narHash": "sha256-GjwzXmdN5SVTT0RIZ11uDTQxaHLTLt9/AbBeIHNfidQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "490f6174c03132bf8f078d0f3a6e5890a47f9b30", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-22.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-2205_6": { + "locked": { + "lastModified": 1653936696, + "narHash": "sha256-M6bJShji9AIDZ7Kh7CPwPBPb/T7RiVev2PAcOi4fxDQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "ce6aa13369b667ac2542593170993504932eb836", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "22.05", + "repo": "nixpkgs", + "type": "github" + } + }, "nixpkgs-latest": { "locked": { "lastModified": 1666809571, @@ -1311,6 +1344,7 @@ "nixpkgs-2111": [ "nixpkgs-2111" ], + "nixpkgs-2205": "nixpkgs-2205_6", "nixpkgs-latest": [ "nixpkgs-latest" ], @@ -1319,16 +1353,16 @@ ] }, "locked": { - "lastModified": 1659450065, - "narHash": "sha256-x6B9sjrZaTite4TSLLyOWfmG3JJbOZuGUNMDZ1f4qhk=", + "lastModified": 1667344793, + "narHash": "sha256-xbnqP7DL3rkjslh7wUGghiAv9ksbEebMih31YY/5nxg=", "owner": "liqwid-labs", "repo": "plutarch-quickcheck", - "rev": "2c5b77f1a622ce68d80a09b286eb0ac85527ff26", + "rev": "4d369eccd35193ce723587d12c4eb2dfa21a824e", "type": "github" }, "original": { "owner": "liqwid-labs", - "ref": "staging", + "ref": "main", "repo": "plutarch-quickcheck", "type": "github" } diff --git a/flake.nix b/flake.nix index d76986c..a669865 100644 --- a/flake.nix +++ b/flake.nix @@ -59,7 +59,7 @@ inputs.ply.follows = "ply"; }; plutarch-quickcheck = { - url = "github:liqwid-labs/plutarch-quickcheck?ref=staging"; + url = "github:liqwid-labs/plutarch-quickcheck?ref=main"; inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs-latest.follows = "nixpkgs-latest"; inputs.nixpkgs-2111.follows = "nixpkgs-2111";