Merge branch 'staging' into seungheonoh/updatepse
This commit is contained in:
commit
dac9dc2394
42 changed files with 2344 additions and 1716 deletions
2
.github/pull_request_template.md
vendored
2
.github/pull_request_template.md
vendored
|
|
@ -6,6 +6,6 @@
|
||||||
|
|
||||||
- [ ] I have ensured documentation and testing are thorough.
|
- [ ] I have ensured documentation and testing are thorough.
|
||||||
- [ ] I have updated the changelog.
|
- [ ] 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 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.
|
- [ ] I have followed the code standards to the best of my ability or have documented carefully where and why I haven't.
|
||||||
|
|
|
||||||
29
CHANGELOG.md
29
CHANGELOG.md
|
|
@ -6,6 +6,35 @@ This format is based on [Keep A Changelog](https://keepachangelog.com/en/1.0.0).
|
||||||
|
|
||||||
### Modified
|
### 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.
|
- Fix several vulnerabilities and bugs found in both proposal and governor scripts.
|
||||||
|
|
||||||
Including:
|
Including:
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,13 @@
|
||||||
module Main (main) where
|
module Main (main) where
|
||||||
|
|
||||||
import Agora.Bootstrap qualified as Bootstrap
|
import Agora.Bootstrap qualified as Bootstrap
|
||||||
import Agora.Linker
|
import Agora.Linker (linker)
|
||||||
import Data.Default (def)
|
import Data.Default (def)
|
||||||
import ScriptExport.Export
|
import ScriptExport.Export (exportMain)
|
||||||
import ScriptExport.Types
|
import ScriptExport.Types (
|
||||||
|
Builders,
|
||||||
|
insertScriptExportWithLinker,
|
||||||
|
)
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = exportMain builders
|
main = exportMain builders
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
|
||||||
|
|
||||||
|
{-# HLINT ignore "Redundant bracket" #-}
|
||||||
|
|
||||||
{- |
|
{- |
|
||||||
Module : Property.Governor
|
Module : Property.Governor
|
||||||
Maintainer : seungheon.ooh@gmail.com
|
Maintainer : seungheon.ooh@gmail.com
|
||||||
|
|
@ -7,19 +11,35 @@ Property model and tests for 'Governor' related functions
|
||||||
-}
|
-}
|
||||||
module Property.Governor (props) where
|
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.Governor.Scripts (governorPolicy)
|
||||||
import Agora.Proposal (
|
import Agora.Proposal (
|
||||||
ProposalId (ProposalId),
|
ProposalId (ProposalId),
|
||||||
ProposalThresholds (ProposalThresholds),
|
ProposalThresholds (
|
||||||
|
ProposalThresholds
|
||||||
|
),
|
||||||
)
|
)
|
||||||
import Agora.Proposal.Time (
|
import Agora.Proposal.Time (
|
||||||
MaxTimeRangeWidth (MaxTimeRangeWidth),
|
MaxTimeRangeWidth (MaxTimeRangeWidth),
|
||||||
ProposalTimingConfig (ProposalTimingConfig),
|
ProposalTimingConfig (ProposalTimingConfig),
|
||||||
)
|
)
|
||||||
import Data.Default.Class (Default (def))
|
import Data.Default (def)
|
||||||
import Data.Tagged (Tagged (Tagged))
|
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.Api.V2 (PScriptContext)
|
||||||
import Plutarch.Builtin (pforgetData)
|
import Plutarch.Builtin (pforgetData)
|
||||||
import Plutarch.Context (
|
import Plutarch.Context (
|
||||||
|
|
@ -34,31 +54,42 @@ import Plutarch.Context (
|
||||||
withRef,
|
withRef,
|
||||||
withValue,
|
withValue,
|
||||||
)
|
)
|
||||||
|
import Plutarch.Evaluate (evalTerm)
|
||||||
import Plutarch.Extra.AssetClass (assetClassValue)
|
import Plutarch.Extra.AssetClass (assetClassValue)
|
||||||
import PlutusLedgerApi.V2 (
|
import Plutarch.Extra.Compile (mustCompile)
|
||||||
ScriptContext (scriptContextTxInfo),
|
import Plutarch.Test.QuickCheck (
|
||||||
TxInInfo (txInInfoOutRef),
|
Equality (OnPEq),
|
||||||
TxInfo (txInfoInputs, txInfoMint, txInfoOutputs),
|
Partiality (ByComplete),
|
||||||
TxOut (txOutValue),
|
TestableTerm (TestableTerm),
|
||||||
|
haskEquiv,
|
||||||
|
pconstantT,
|
||||||
|
shouldCrash,
|
||||||
|
shouldRun,
|
||||||
)
|
)
|
||||||
|
import PlutusLedgerApi.V2 (Script, ScriptContext)
|
||||||
import Property.Generator (genInput, genOutput)
|
import Property.Generator (genInput, genOutput)
|
||||||
import Sample.Shared (
|
import Sample.Shared (
|
||||||
|
deterministicTracingConfig,
|
||||||
governor,
|
governor,
|
||||||
governorAssetClass,
|
governorAssetClass,
|
||||||
governorSymbol,
|
governorSymbol,
|
||||||
governorValidatorHash,
|
governorValidatorHash,
|
||||||
gstUTXORef,
|
gstUTXORef,
|
||||||
)
|
)
|
||||||
import Test.Tasty (TestTree)
|
import Test.QuickCheck (
|
||||||
import Test.Tasty.Plutarch.Property (classifiedPropertyNative)
|
Arbitrary (arbitrary),
|
||||||
import Test.Tasty.QuickCheck (
|
|
||||||
Gen,
|
Gen,
|
||||||
Property,
|
Property,
|
||||||
|
arbitraryBoundedEnum,
|
||||||
|
checkCoverage,
|
||||||
choose,
|
choose,
|
||||||
chooseInteger,
|
chooseInteger,
|
||||||
|
cover,
|
||||||
|
forAll,
|
||||||
listOf1,
|
listOf1,
|
||||||
testProperty,
|
|
||||||
)
|
)
|
||||||
|
import Test.Tasty (TestTree, adjustOption, testGroup)
|
||||||
|
import Test.Tasty.QuickCheck (QuickCheckTests, testProperty)
|
||||||
|
|
||||||
data GovernorDatumCases
|
data GovernorDatumCases
|
||||||
= ExecuteLE0
|
= ExecuteLE0
|
||||||
|
|
@ -67,172 +98,211 @@ data GovernorDatumCases
|
||||||
| VoteLE0
|
| VoteLE0
|
||||||
| CosignLE0
|
| CosignLE0
|
||||||
| Correct
|
| Correct
|
||||||
deriving stock (Eq, Show)
|
deriving stock (Eq, Show, Enum, Bounded)
|
||||||
|
deriving anyclass (Universe, Finite)
|
||||||
|
|
||||||
instance Universe GovernorDatumCases where
|
instance Arbitrary GovernorDatumCases where
|
||||||
universe =
|
arbitrary = arbitraryBoundedEnum
|
||||||
[ ExecuteLE0
|
|
||||||
, CreateLE0
|
|
||||||
, VoteLE0
|
|
||||||
, CosignLE0
|
|
||||||
, Correct
|
|
||||||
]
|
|
||||||
|
|
||||||
instance Finite GovernorDatumCases where
|
{- | Property that checks `pisGovernorDatumValid` behaves as intended by
|
||||||
universeF = universe
|
comparing it to a simple haskell implementation.
|
||||||
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.
|
|
||||||
-}
|
-}
|
||||||
governorDatumValidProperty :: Property
|
governorDatumValidProperty :: Property
|
||||||
governorDatumValidProperty =
|
governorDatumValidProperty =
|
||||||
classifiedPropertyNative gen (const []) expected classifier pisGovernorDatumValid
|
haskEquiv @( 'OnPEq) @( 'ByComplete)
|
||||||
|
isValidModelImpl
|
||||||
|
(TestableTerm pisGovernorDatumValid)
|
||||||
|
(genDatum :* Nil)
|
||||||
where
|
where
|
||||||
classifier :: GovernorDatum -> GovernorDatumCases
|
genDatum :: Gen (TestableTerm PGovernorDatum)
|
||||||
classifier
|
genDatum = pconstantT <$> (arbitrary >>= genDatumForCase)
|
||||||
( (.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
|
|
||||||
where
|
where
|
||||||
taggedInteger p = Tagged <$> chooseInteger p
|
genDatumForCase :: GovernorDatumCases -> Gen GovernorDatum
|
||||||
genProposalThresholds :: GovernorDatumCases -> Gen ProposalThresholds
|
genDatumForCase c = do
|
||||||
genProposalThresholds c = do
|
thres <- genProposalThresholds c
|
||||||
let validGT = taggedInteger (0, 1000000000)
|
|
||||||
execute <- validGT
|
|
||||||
create <- validGT
|
|
||||||
toVoting <- validGT
|
|
||||||
vote <- validGT
|
|
||||||
cosign <- validGT
|
|
||||||
le0 <- taggedInteger (-1000, -1)
|
|
||||||
|
|
||||||
case c of
|
let timing = ProposalTimingConfig 0 0 0 0 0 0
|
||||||
ExecuteLE0 ->
|
pure $
|
||||||
-- execute < 0
|
GovernorDatum thres (ProposalId 0) timing (MaxTimeRangeWidth 1) 3
|
||||||
return $ ProposalThresholds le0 create toVoting vote cosign
|
where
|
||||||
CreateLE0 ->
|
taggedInteger p = Tagged <$> chooseInteger p
|
||||||
-- c < 0
|
genProposalThresholds :: GovernorDatumCases -> Gen ProposalThresholds
|
||||||
return $ ProposalThresholds execute le0 toVoting vote cosign
|
genProposalThresholds c = do
|
||||||
ToVotingLE0 ->
|
let validGT = taggedInteger (0, 1000000000)
|
||||||
return $ ProposalThresholds execute create le0 vote cosign
|
execute <- validGT
|
||||||
VoteLE0 ->
|
create <- validGT
|
||||||
-- vote < 0
|
toVoting <- validGT
|
||||||
return $ ProposalThresholds execute create toVoting le0 cosign
|
vote <- validGT
|
||||||
CosignLE0 ->
|
cosign <- validGT
|
||||||
return $ ProposalThresholds execute create toVoting vote le0
|
le0 <- taggedInteger (-1000, -1)
|
||||||
Correct ->
|
|
||||||
return $ ProposalThresholds execute create toVoting vote cosign
|
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
|
data GovernorPolicyCases
|
||||||
= ReferenceUTXONotSpent
|
= ReferenceUTXONotSpent
|
||||||
| IncorrectAmountOfTokenMinted
|
| IncorrectAmountOfTokenMinted
|
||||||
| GovernorOutputNotFound
|
| GovernorOutputNotFound
|
||||||
| GovernorPolicyCorrect
|
|
||||||
deriving stock (Eq, Show)
|
deriving stock (Eq, Show)
|
||||||
|
|
||||||
instance Universe GovernorPolicyCases where
|
governorMintingPolicyTests :: [TestTree]
|
||||||
universe =
|
governorMintingPolicyTests =
|
||||||
[ ReferenceUTXONotSpent
|
[ mkGovMintingCasePropertyTest
|
||||||
, IncorrectAmountOfTokenMinted
|
"Reference input spend test"
|
||||||
, GovernorOutputNotFound
|
ReferenceUTXONotSpent
|
||||||
, GovernorPolicyCorrect
|
"Spent"
|
||||||
]
|
"Not spent"
|
||||||
|
, mkGovMintingCasePropertyTest
|
||||||
|
"Amount of token minted test"
|
||||||
|
IncorrectAmountOfTokenMinted
|
||||||
|
"Correct"
|
||||||
|
"Incorrect"
|
||||||
|
, mkGovMintingCasePropertyTest
|
||||||
|
"Governor output presense"
|
||||||
|
GovernorOutputNotFound
|
||||||
|
"Present"
|
||||||
|
"Absent"
|
||||||
|
]
|
||||||
|
|
||||||
instance Finite GovernorPolicyCases where
|
{- | Creates a property by compiling governorPolicy script with given arguments
|
||||||
universeF = universe
|
and checking if it runs as expected by a test.
|
||||||
cardinality = Tagged 4
|
-}
|
||||||
|
governorPolicyValid :: ScriptContext -> Bool -> Property
|
||||||
|
governorPolicyValid ctx shouldSucceed =
|
||||||
|
let mp = mkPolicyScript ctx in if shouldSucceed then shouldRun mp else shouldCrash mp
|
||||||
|
|
||||||
governorMintingProperty :: Property
|
{-# INLINEABLE mkPolicyScript #-}
|
||||||
governorMintingProperty =
|
mkPolicyScript :: ScriptContext -> Script
|
||||||
classifiedPropertyNative gen (const []) expected classifier actual
|
mkPolicyScript ctx = mustCompile (go # pconstant ctx)
|
||||||
where
|
where
|
||||||
{- Note:
|
go :: forall (s :: S). Term s (PScriptContext :--> POpaque)
|
||||||
I don't think it's easily possible to randomize orefs. We can't really pass pass `Governor` type to `actual` function.
|
go = loudEval $
|
||||||
-}
|
plam $ \sc ->
|
||||||
gst = assetClassValue governorAssetClass 1
|
governorPolicy
|
||||||
mintAmount x = mint . mconcat $ replicate x gst
|
# pconstant (view #gstOutRef governor)
|
||||||
outputToGov =
|
# pforgetData (pconstantData ())
|
||||||
output $
|
# sc
|
||||||
mconcat
|
|
||||||
[ script governorValidatorHash
|
|
||||||
, withValue gst
|
|
||||||
, withDatum govDatum
|
|
||||||
]
|
|
||||||
referencedInput = input $ withRef gstUTXORef
|
|
||||||
|
|
||||||
govDatum :: GovernorDatum
|
-- | Prepares a minting policy test for given policy error case.
|
||||||
govDatum =
|
mkGovMintingCasePropertyTest ::
|
||||||
GovernorDatum
|
String ->
|
||||||
{ proposalThresholds = def
|
GovernorPolicyCases ->
|
||||||
, nextProposalId = ProposalId 0
|
String ->
|
||||||
, proposalTimings = def
|
String ->
|
||||||
, createProposalTimeRangeMaxWidth = def
|
TestTree
|
||||||
, maximumProposalsPerStake = 3
|
mkGovMintingCasePropertyTest name case' positiveCaseName negativeCaseName =
|
||||||
}
|
testProperty name $
|
||||||
|
forAll (gen case') $
|
||||||
gen :: GovernorPolicyCases -> Gen ScriptContext
|
\(ctx, valid) ->
|
||||||
|
checkCoverage $
|
||||||
|
cover 48 valid positiveCaseName $
|
||||||
|
cover 48 (not valid) negativeCaseName $
|
||||||
|
governorPolicyValid ctx valid
|
||||||
|
where
|
||||||
|
gen :: GovernorPolicyCases -> Gen (ScriptContext, Bool)
|
||||||
gen c = do
|
gen c = do
|
||||||
inputs <- fmap mconcat . listOf1 $ genInput @MintingBuilder
|
inputs <- fmap mconcat . listOf1 $ genInput @MintingBuilder
|
||||||
outputs <- fmap mconcat . listOf1 $ genOutput @MintingBuilder
|
outputs <- fmap mconcat . listOf1 $ genOutput @MintingBuilder
|
||||||
toks <- choose (2, 100)
|
toks <- choose (2, 100)
|
||||||
|
|
||||||
|
valid <- arbitrary
|
||||||
let comp =
|
let comp =
|
||||||
case c of
|
if valid
|
||||||
ReferenceUTXONotSpent -> outputToGov <> mintAmount 1
|
then referencedInput <> outputToGov <> mintAmount 1
|
||||||
IncorrectAmountOfTokenMinted -> referencedInput <> outputToGov <> mintAmount toks
|
else case c of
|
||||||
GovernorOutputNotFound -> referencedInput <> mintAmount 1
|
ReferenceUTXONotSpent -> outputToGov <> mintAmount 1
|
||||||
GovernorPolicyCorrect -> referencedInput <> outputToGov <> mintAmount 1
|
IncorrectAmountOfTokenMinted ->
|
||||||
|
referencedInput
|
||||||
|
<> outputToGov
|
||||||
|
<> mintAmount toks
|
||||||
|
GovernorOutputNotFound -> referencedInput <> mintAmount 1
|
||||||
|
|
||||||
return . buildMinting' $ inputs <> outputs <> comp <> withMinting governorSymbol
|
let ctx =
|
||||||
|
buildMinting' $
|
||||||
expected :: ScriptContext -> Maybe ()
|
inputs
|
||||||
expected sc =
|
<> outputs
|
||||||
case classifier sc of
|
<> comp
|
||||||
GovernorPolicyCorrect -> Just ()
|
<> withMinting
|
||||||
_ -> Nothing
|
governorSymbol
|
||||||
|
pure (ctx, valid)
|
||||||
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
|
|
||||||
where
|
where
|
||||||
txinfo = scriptContextTxInfo sc
|
govDatum :: GovernorDatum
|
||||||
minted = txInfoMint txinfo
|
govDatum =
|
||||||
refInputNotExists = gstUTXORef `notElem` (txInInfoOutRef <$> txInfoInputs txinfo)
|
GovernorDatum
|
||||||
govOutputNotExists = gst `notElem` (txOutValue <$> txInfoOutputs txinfo)
|
{ 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 :: [TestTree]
|
||||||
props =
|
props =
|
||||||
[ testProperty "governorDatumValid" governorDatumValidProperty
|
[ adjustOption go . testProperty "governorDatumValid" $ governorDatumValidProperty
|
||||||
, testProperty "governorPolicy" governorMintingProperty
|
, 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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -17,12 +17,12 @@ import Agora.Effect.GovernorMutation (
|
||||||
import Agora.Governor (GovernorDatum (..), GovernorRedeemer (MutateGovernor))
|
import Agora.Governor (GovernorDatum (..), GovernorRedeemer (MutateGovernor))
|
||||||
import Agora.Proposal (ProposalId (..), ProposalThresholds (..))
|
import Agora.Proposal (ProposalId (..), ProposalThresholds (..))
|
||||||
import Agora.SafeMoney (AuthorityTokenTag)
|
import Agora.SafeMoney (AuthorityTokenTag)
|
||||||
import Agora.Utils (validatorHashToTokenName)
|
|
||||||
import Data.Default.Class (Default (def))
|
import Data.Default.Class (Default (def))
|
||||||
import Data.Map ((!))
|
import Data.Map ((!))
|
||||||
import Data.Tagged (Tagged (..))
|
import Data.Tagged (Tagged (..))
|
||||||
import Plutarch.Api.V2 (validatorHash)
|
import Plutarch.Api.V2 (validatorHash)
|
||||||
import Plutarch.Extra.AssetClass (AssetClass (AssetClass), assetClassValue)
|
import Plutarch.Extra.AssetClass (AssetClass (AssetClass), assetClassValue)
|
||||||
|
import Plutarch.Extra.ScriptContext (validatorHashToTokenName)
|
||||||
import PlutusLedgerApi.V1 qualified as Interval (always)
|
import PlutusLedgerApi.V1 qualified as Interval (always)
|
||||||
import PlutusLedgerApi.V1.Address (scriptHashAddress)
|
import PlutusLedgerApi.V1.Address (scriptHashAddress)
|
||||||
import PlutusLedgerApi.V1.Value qualified as Value (
|
import PlutusLedgerApi.V1.Value qualified as Value (
|
||||||
|
|
@ -114,7 +114,7 @@ mkEffectTxInfo newGovDatum =
|
||||||
, nextProposalId = ProposalId 0
|
, nextProposalId = ProposalId 0
|
||||||
, proposalTimings = def
|
, proposalTimings = def
|
||||||
, createProposalTimeRangeMaxWidth = def
|
, createProposalTimeRangeMaxWidth = def
|
||||||
, maximumProposalsPerStake = 3
|
, maximumCreatedProposalsPerStake = 3
|
||||||
}
|
}
|
||||||
governorInputDatum :: Datum
|
governorInputDatum :: Datum
|
||||||
governorInputDatum = Datum $ toBuiltinData governorInputDatum'
|
governorInputDatum = Datum $ toBuiltinData governorInputDatum'
|
||||||
|
|
@ -186,7 +186,7 @@ validNewGovernorDatum =
|
||||||
, nextProposalId = ProposalId 42
|
, nextProposalId = ProposalId 42
|
||||||
, proposalTimings = def
|
, proposalTimings = def
|
||||||
, createProposalTimeRangeMaxWidth = def
|
, createProposalTimeRangeMaxWidth = def
|
||||||
, maximumProposalsPerStake = 3
|
, maximumCreatedProposalsPerStake = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
invalidNewGovernorDatum :: GovernorDatum
|
invalidNewGovernorDatum :: GovernorDatum
|
||||||
|
|
@ -199,5 +199,5 @@ invalidNewGovernorDatum =
|
||||||
, nextProposalId = ProposalId 42
|
, nextProposalId = ProposalId 42
|
||||||
, proposalTimings = def
|
, proposalTimings = def
|
||||||
, createProposalTimeRangeMaxWidth = def
|
, createProposalTimeRangeMaxWidth = def
|
||||||
, maximumProposalsPerStake = 3
|
, maximumCreatedProposalsPerStake = 3
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ import PlutusLedgerApi.V2 (
|
||||||
ValidatorHash,
|
ValidatorHash,
|
||||||
)
|
)
|
||||||
import Sample.Shared (
|
import Sample.Shared (
|
||||||
deterministicTracingConfing,
|
deterministicTracingConfig,
|
||||||
minAda,
|
minAda,
|
||||||
)
|
)
|
||||||
import Sample.Shared qualified as Shared
|
import Sample.Shared qualified as Shared
|
||||||
|
|
@ -72,7 +72,7 @@ data Parameters = Parameters
|
||||||
-- ^ Whether the 'GovernorDatum.proposalThresholds' field of the output
|
-- ^ Whether the 'GovernorDatum.proposalThresholds' field of the output
|
||||||
-- governor datum is valid or not.
|
-- governor datum is valid or not.
|
||||||
, datumMaxTimeRangeWidthValid :: Bool
|
, datumMaxTimeRangeWidthValid :: Bool
|
||||||
-- ^ Whether the 'GovernorDatum.maximumProposalsPerStake'field of the
|
-- ^ Whether the 'GovernorDatum.maximumCreatedProposalsPerStake'field of the
|
||||||
-- output governor datum is valid or not.
|
-- output governor datum is valid or not.
|
||||||
, datumTimingConfigValid :: Bool
|
, datumTimingConfigValid :: Bool
|
||||||
-- ^ Whether the 'GovernorDatum.proposalTimings'field of the output
|
-- ^ Whether the 'GovernorDatum.proposalTimings'field of the output
|
||||||
|
|
@ -96,7 +96,7 @@ validGovernorOutputDatum =
|
||||||
, nextProposalId = ProposalId 0
|
, nextProposalId = ProposalId 0
|
||||||
, proposalTimings = def
|
, proposalTimings = def
|
||||||
, createProposalTimeRangeMaxWidth = def
|
, createProposalTimeRangeMaxWidth = def
|
||||||
, maximumProposalsPerStake = 3
|
, maximumCreatedProposalsPerStake = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
invalidProposalThresholds :: ProposalThresholds
|
invalidProposalThresholds :: ProposalThresholds
|
||||||
|
|
@ -106,7 +106,7 @@ invalidMaxTimeRangeWidth :: MaxTimeRangeWidth
|
||||||
invalidMaxTimeRangeWidth = MaxTimeRangeWidth 0
|
invalidMaxTimeRangeWidth = MaxTimeRangeWidth 0
|
||||||
|
|
||||||
invalidProposalTimings :: ProposalTimingConfig
|
invalidProposalTimings :: ProposalTimingConfig
|
||||||
invalidProposalTimings = ProposalTimingConfig (-1) (-1) (-1) (-1)
|
invalidProposalTimings = ProposalTimingConfig (-1) (-1) (-1) (-1) (-1) (-1)
|
||||||
|
|
||||||
witnessRef :: TxOutRef
|
witnessRef :: TxOutRef
|
||||||
witnessRef = TxOutRef "b0353c22b0bd6c5296a8eef160ba25d90b5dc82a9bb8bdaa6823ffc19515d6ad" 0
|
witnessRef = TxOutRef "b0353c22b0bd6c5296a8eef160ba25d90b5dc82a9bb8bdaa6823ffc19515d6ad" 0
|
||||||
|
|
@ -124,7 +124,7 @@ scripts =
|
||||||
(fmap (view #script) . view #scripts)
|
(fmap (view #script) . view #scripts)
|
||||||
( runLinker
|
( runLinker
|
||||||
linker
|
linker
|
||||||
(agoraScripts deterministicTracingConfing)
|
(agoraScripts deterministicTracingConfig)
|
||||||
governor
|
governor
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ module Sample.Governor.Mutate (
|
||||||
|
|
||||||
import Agora.Governor (GovernorDatum (..), GovernorRedeemer (MutateGovernor))
|
import Agora.Governor (GovernorDatum (..), GovernorRedeemer (MutateGovernor))
|
||||||
import Agora.Proposal (ProposalId (ProposalId), ProposalThresholds (..))
|
import Agora.Proposal (ProposalId (ProposalId), ProposalThresholds (..))
|
||||||
import Agora.Utils (scriptHashToTokenName)
|
|
||||||
import Data.Default (def)
|
import Data.Default (def)
|
||||||
import Data.Map ((!))
|
import Data.Map ((!))
|
||||||
import Plutarch.Api.V2 (PMintingPolicy, mintingPolicySymbol, mkMintingPolicy, validatorHash)
|
import Plutarch.Api.V2 (PMintingPolicy, mintingPolicySymbol, mkMintingPolicy, validatorHash)
|
||||||
|
|
@ -33,6 +32,7 @@ import Plutarch.Context (
|
||||||
withValue,
|
withValue,
|
||||||
)
|
)
|
||||||
import Plutarch.Extra.AssetClass (assetClassValue)
|
import Plutarch.Extra.AssetClass (assetClassValue)
|
||||||
|
import Plutarch.Extra.ScriptContext (scriptHashToTokenName)
|
||||||
import PlutusLedgerApi.V1.Value qualified as Value
|
import PlutusLedgerApi.V1.Value qualified as Value
|
||||||
import PlutusLedgerApi.V2 (
|
import PlutusLedgerApi.V2 (
|
||||||
CurrencySymbol (CurrencySymbol),
|
CurrencySymbol (CurrencySymbol),
|
||||||
|
|
@ -105,7 +105,7 @@ governorInputDatum =
|
||||||
, nextProposalId = ProposalId 0
|
, nextProposalId = ProposalId 0
|
||||||
, proposalTimings = def
|
, proposalTimings = def
|
||||||
, createProposalTimeRangeMaxWidth = def
|
, createProposalTimeRangeMaxWidth = def
|
||||||
, maximumProposalsPerStake = 3
|
, maximumCreatedProposalsPerStake = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
mkGovernorOutputDatum ::
|
mkGovernorOutputDatum ::
|
||||||
|
|
@ -115,7 +115,7 @@ mkGovernorOutputDatum DatumValid =
|
||||||
Just $
|
Just $
|
||||||
toData $
|
toData $
|
||||||
governorInputDatum
|
governorInputDatum
|
||||||
{ maximumProposalsPerStake = 4
|
{ maximumCreatedProposalsPerStake = 4
|
||||||
}
|
}
|
||||||
mkGovernorOutputDatum ValueInvalid =
|
mkGovernorOutputDatum ValueInvalid =
|
||||||
let invalidProposalThresholds =
|
let invalidProposalThresholds =
|
||||||
|
|
|
||||||
|
|
@ -35,12 +35,14 @@ module Sample.Proposal.Advance (
|
||||||
mkMintGATsWithoutTagBundle,
|
mkMintGATsWithoutTagBundle,
|
||||||
mkBadGovernorOutputDatumBundle,
|
mkBadGovernorOutputDatumBundle,
|
||||||
mkUnexpectedOutputStakeBundles,
|
mkUnexpectedOutputStakeBundles,
|
||||||
|
mkFastforwardToFinishBundles,
|
||||||
|
mkBadGovernorRedeemerBundle,
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Agora.Governor (
|
import Agora.Governor (
|
||||||
Governor (..),
|
Governor (..),
|
||||||
GovernorDatum (..),
|
GovernorDatum (..),
|
||||||
GovernorRedeemer (MintGATs),
|
GovernorRedeemer (CreateProposal, MintGATs),
|
||||||
)
|
)
|
||||||
import Agora.Proposal (
|
import Agora.Proposal (
|
||||||
ProposalDatum (..),
|
ProposalDatum (..),
|
||||||
|
|
@ -67,7 +69,6 @@ import Agora.SafeMoney (AuthorityTokenTag, GTTag)
|
||||||
import Agora.Stake (
|
import Agora.Stake (
|
||||||
StakeDatum (..),
|
StakeDatum (..),
|
||||||
)
|
)
|
||||||
import Agora.Utils (scriptHashToTokenName)
|
|
||||||
import Control.Applicative (liftA2)
|
import Control.Applicative (liftA2)
|
||||||
import Control.Monad.State (execState, modify, when)
|
import Control.Monad.State (execState, modify, when)
|
||||||
import Data.Default (def)
|
import Data.Default (def)
|
||||||
|
|
@ -85,10 +86,12 @@ import Plutarch.Context (
|
||||||
timeRange,
|
timeRange,
|
||||||
withDatum,
|
withDatum,
|
||||||
withInlineDatum,
|
withInlineDatum,
|
||||||
|
withRedeemer,
|
||||||
withRef,
|
withRef,
|
||||||
withValue,
|
withValue,
|
||||||
)
|
)
|
||||||
import Plutarch.Extra.AssetClass (AssetClass (AssetClass), assetClassValue)
|
import Plutarch.Extra.AssetClass (AssetClass (AssetClass), assetClassValue)
|
||||||
|
import Plutarch.Extra.ScriptContext (scriptHashToTokenName)
|
||||||
import Plutarch.Lift (PLifted, PUnsafeLiftDecl)
|
import Plutarch.Lift (PLifted, PUnsafeLiftDecl)
|
||||||
import PlutusLedgerApi.V2 (
|
import PlutusLedgerApi.V2 (
|
||||||
Credential (PubKeyCredential),
|
Credential (PubKeyCredential),
|
||||||
|
|
@ -100,6 +103,7 @@ import PlutusLedgerApi.V2 (
|
||||||
TxOutRef (TxOutRef),
|
TxOutRef (TxOutRef),
|
||||||
ValidatorHash,
|
ValidatorHash,
|
||||||
)
|
)
|
||||||
|
import PlutusTx qualified
|
||||||
import Sample.Proposal.Shared (
|
import Sample.Proposal.Shared (
|
||||||
governorTxRef,
|
governorTxRef,
|
||||||
proposalTxRef,
|
proposalTxRef,
|
||||||
|
|
@ -164,9 +168,18 @@ data ParameterBundle = ParameterBundle
|
||||||
}
|
}
|
||||||
|
|
||||||
-- | Everything about the generated governor stuff.
|
-- | 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
|
{ invalidGovernorOutputDatum :: Bool
|
||||||
-- ^ The output governor datum will be changed.
|
-- ^ The output governor datum will be changed.
|
||||||
|
, governorRedeemer :: redeemer
|
||||||
}
|
}
|
||||||
|
|
||||||
-- | Everything about the generated authority token stuff.
|
-- | Everything about the generated authority token stuff.
|
||||||
|
|
@ -278,7 +291,7 @@ mkVotes ps =
|
||||||
|
|
||||||
-- | The starting time of every generated proposal.
|
-- | The starting time of every generated proposal.
|
||||||
proposalStartingTime :: POSIXTime
|
proposalStartingTime :: POSIXTime
|
||||||
proposalStartingTime = 0
|
proposalStartingTime = 100
|
||||||
|
|
||||||
-- | Create the input proposal datum given the parameters.
|
-- | Create the input proposal datum given the parameters.
|
||||||
mkProposalInputDatum :: ProposalParameters -> ProposalDatum
|
mkProposalInputDatum :: ProposalParameters -> ProposalDatum
|
||||||
|
|
@ -413,14 +426,14 @@ governorInputDatum =
|
||||||
, nextProposalId = ProposalId 42
|
, nextProposalId = ProposalId 42
|
||||||
, proposalTimings = def
|
, proposalTimings = def
|
||||||
, createProposalTimeRangeMaxWidth = def
|
, createProposalTimeRangeMaxWidth = def
|
||||||
, maximumProposalsPerStake = 3
|
, maximumCreatedProposalsPerStake = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
-- | Create the output governor datum given the parameters.
|
-- | Create the output governor datum given the parameters.
|
||||||
mkGovernorOutputDatum :: GovernorParameters -> GovernorDatum
|
mkGovernorOutputDatum :: GovernorParameters -> GovernorDatum
|
||||||
mkGovernorOutputDatum ps =
|
mkGovernorOutputDatum ps =
|
||||||
if ps.invalidGovernorOutputDatum
|
if ps.invalidGovernorOutputDatum
|
||||||
then governorInputDatum {maximumProposalsPerStake = 15}
|
then governorInputDatum {maximumCreatedProposalsPerStake = 15}
|
||||||
else governorInputDatum
|
else governorInputDatum
|
||||||
|
|
||||||
-- | Reference to the governor UTXO.
|
-- | Reference to the governor UTXO.
|
||||||
|
|
@ -431,7 +444,7 @@ governorRef = TxOutRef governorTxRef 2
|
||||||
governor validator.
|
governor validator.
|
||||||
-}
|
-}
|
||||||
mkGovernorBuilder :: forall b. CombinableBuilder b => GovernorParameters -> b
|
mkGovernorBuilder :: forall b. CombinableBuilder b => GovernorParameters -> b
|
||||||
mkGovernorBuilder ps =
|
mkGovernorBuilder ps@(GovernorParameters _ redeemer) =
|
||||||
let gst = assetClassValue governorAssetClass 1
|
let gst = assetClassValue governorAssetClass 1
|
||||||
value = sortValue $ gst <> minAda
|
value = sortValue $ gst <> minAda
|
||||||
in mconcat
|
in mconcat
|
||||||
|
|
@ -441,6 +454,7 @@ mkGovernorBuilder ps =
|
||||||
, withValue value
|
, withValue value
|
||||||
, withRef governorRef
|
, withRef governorRef
|
||||||
, withDatum governorInputDatum
|
, withDatum governorInputDatum
|
||||||
|
, withRedeemer redeemer
|
||||||
]
|
]
|
||||||
, output $
|
, output $
|
||||||
mconcat
|
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
|
-- * Authority Token
|
||||||
|
|
@ -537,16 +545,22 @@ mkTestTree name pb val =
|
||||||
proposalInputDatum
|
proposalInputDatum
|
||||||
proposalRedeemer
|
proposalRedeemer
|
||||||
(spend proposalRef)
|
(spend proposalRef)
|
||||||
|
|
||||||
governor =
|
governor =
|
||||||
maybe [] singleton $
|
maybe
|
||||||
testValidator
|
[]
|
||||||
(fromJust val.forGovernorValidator)
|
( singleton
|
||||||
"governor"
|
. ( \(GovernorParameters _ governorRedeemer) ->
|
||||||
governorValidator
|
testValidator
|
||||||
governorInputDatum
|
(fromJust val.forGovernorValidator)
|
||||||
governorRedeemer
|
"governor"
|
||||||
(spend governorRef)
|
governorValidator
|
||||||
<$ pb.governorParameters
|
governorInputDatum
|
||||||
|
governorRedeemer
|
||||||
|
(spend governorRef)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(pb.governorParameters)
|
||||||
|
|
||||||
authority = case pb.authorityTokenParameters of
|
authority = case pb.authorityTokenParameters of
|
||||||
[] -> []
|
[] -> []
|
||||||
|
|
@ -715,20 +729,20 @@ mkMockEffects useAuthScript n = effects
|
||||||
effectsPerGroup
|
effectsPerGroup
|
||||||
(zip effectScripts effectMetadata)
|
(zip effectScripts effectMetadata)
|
||||||
|
|
||||||
numberOfVotesThatExceedsTheMinimumRequirement :: Integer
|
numberOfVotesThatJustMeetsTheMinimumRequirement :: Integer
|
||||||
numberOfVotesThatExceedsTheMinimumRequirement =
|
numberOfVotesThatJustMeetsTheMinimumRequirement =
|
||||||
untag (def @ProposalThresholds).execute + 1
|
untag (def @ProposalThresholds).execute
|
||||||
|
|
||||||
mkWinnerVotes :: Index -> (Winner, Integer)
|
mkWinnerVotes :: Index -> (Winner, Integer)
|
||||||
mkWinnerVotes idx =
|
mkWinnerVotes idx =
|
||||||
( EffectAt idx
|
( EffectAt idx
|
||||||
, numberOfVotesThatExceedsTheMinimumRequirement
|
, numberOfVotesThatJustMeetsTheMinimumRequirement
|
||||||
)
|
)
|
||||||
|
|
||||||
ambiguousWinnerVotes :: (Winner, Integer)
|
ambiguousWinnerVotes :: (Winner, Integer)
|
||||||
ambiguousWinnerVotes =
|
ambiguousWinnerVotes =
|
||||||
( All
|
( All
|
||||||
, numberOfVotesThatExceedsTheMinimumRequirement
|
, numberOfVotesThatJustMeetsTheMinimumRequirement
|
||||||
)
|
)
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
@ -826,6 +840,7 @@ mkValidToNextStateBundle nCosigners nEffects authScript from =
|
||||||
gov =
|
gov =
|
||||||
GovernorParameters
|
GovernorParameters
|
||||||
{ invalidGovernorOutputDatum = False
|
{ invalidGovernorOutputDatum = False
|
||||||
|
, governorRedeemer = MintGATs
|
||||||
}
|
}
|
||||||
in b
|
in b
|
||||||
{ governorParameters = Just gov
|
{ governorParameters = Just gov
|
||||||
|
|
@ -1065,4 +1080,47 @@ mkBadGovernorOutputDatumBundle nCosigners nEffects =
|
||||||
}
|
}
|
||||||
where
|
where
|
||||||
template = mkValidFromLockedBundle nCosigners nEffects
|
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
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,8 @@ import Agora.Proposal.Time (
|
||||||
)
|
)
|
||||||
import Agora.SafeMoney (GTTag)
|
import Agora.SafeMoney (GTTag)
|
||||||
import Agora.Stake (
|
import Agora.Stake (
|
||||||
ProposalLock (Cosigned, Created),
|
ProposalAction (Cosigned, Created),
|
||||||
|
ProposalLock (ProposalLock),
|
||||||
StakeDatum (..),
|
StakeDatum (..),
|
||||||
StakeRedeemer (PermitVote),
|
StakeRedeemer (PermitVote),
|
||||||
)
|
)
|
||||||
|
|
@ -196,7 +197,7 @@ mkStakeInputDatum ps =
|
||||||
amount = mkStakeAmount sps.gtAmount
|
amount = mkStakeAmount sps.gtAmount
|
||||||
owner = mkStakeOwner sps.stakeOwner
|
owner = mkStakeOwner sps.stakeOwner
|
||||||
locks = case sps.stakeOwner of
|
locks = case sps.stakeOwner of
|
||||||
Creator -> [Created defProposalId]
|
Creator -> [ProposalLock defProposalId Created]
|
||||||
_ -> []
|
_ -> []
|
||||||
in StakeDatum
|
in StakeDatum
|
||||||
{ stakedAmount = amount
|
{ stakedAmount = amount
|
||||||
|
|
@ -212,7 +213,7 @@ mkStakeOuputDatum ps =
|
||||||
locks =
|
locks =
|
||||||
if sps.dontUpdateLocks
|
if sps.dontUpdateLocks
|
||||||
then inpDatum.lockedBy
|
then inpDatum.lockedBy
|
||||||
else Cosigned defProposalId : inpDatum.lockedBy
|
else ProposalLock defProposalId Cosigned : inpDatum.lockedBy
|
||||||
in inpDatum {lockedBy = locks}
|
in inpDatum {lockedBy = locks}
|
||||||
|
|
||||||
stakeRedeemer :: StakeRedeemer
|
stakeRedeemer :: StakeRedeemer
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,19 @@ module Sample.Proposal.Create (
|
||||||
timeRangeNotTightParameters,
|
timeRangeNotTightParameters,
|
||||||
timeRangeNotClosedParameters,
|
timeRangeNotClosedParameters,
|
||||||
invalidProposalStatusParameters,
|
invalidProposalStatusParameters,
|
||||||
|
fakeSSTParameters,
|
||||||
|
wrongGovernorRedeemer,
|
||||||
|
wrongGovernorRedeemer1,
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Agora.Governor (
|
import Agora.Governor (
|
||||||
Governor (..),
|
Governor (..),
|
||||||
GovernorDatum (..),
|
GovernorDatum (..),
|
||||||
GovernorRedeemer (CreateProposal),
|
GovernorRedeemer (
|
||||||
|
CreateProposal,
|
||||||
|
MintGATs,
|
||||||
|
MutateGovernor
|
||||||
|
),
|
||||||
)
|
)
|
||||||
import Agora.Proposal (
|
import Agora.Proposal (
|
||||||
ProposalDatum (..),
|
ProposalDatum (..),
|
||||||
|
|
@ -40,7 +47,8 @@ import Agora.Proposal.Time (
|
||||||
)
|
)
|
||||||
import Agora.SafeMoney (GTTag)
|
import Agora.SafeMoney (GTTag)
|
||||||
import Agora.Stake (
|
import Agora.Stake (
|
||||||
ProposalLock (..),
|
ProposalAction (Created, Voted),
|
||||||
|
ProposalLock (ProposalLock),
|
||||||
StakeDatum (..),
|
StakeDatum (..),
|
||||||
StakeRedeemer (PermitVote),
|
StakeRedeemer (PermitVote),
|
||||||
)
|
)
|
||||||
|
|
@ -63,10 +71,14 @@ import Plutarch.Context (
|
||||||
withValue,
|
withValue,
|
||||||
)
|
)
|
||||||
import Plutarch.Extra.AssetClass (assetClassValue)
|
import Plutarch.Extra.AssetClass (assetClassValue)
|
||||||
|
import Plutarch.Extra.ScriptContext (validatorHashToTokenName)
|
||||||
|
import PlutusLedgerApi.V1.Value qualified as Value
|
||||||
import PlutusLedgerApi.V2 (
|
import PlutusLedgerApi.V2 (
|
||||||
Credential (PubKeyCredential),
|
Credential (PubKeyCredential),
|
||||||
POSIXTime (POSIXTime),
|
POSIXTime (POSIXTime),
|
||||||
POSIXTimeRange,
|
POSIXTimeRange,
|
||||||
|
Redeemer (Redeemer),
|
||||||
|
ToData (toBuiltinData),
|
||||||
TxOutRef (TxOutRef),
|
TxOutRef (TxOutRef),
|
||||||
always,
|
always,
|
||||||
)
|
)
|
||||||
|
|
@ -85,6 +97,7 @@ import Sample.Shared (
|
||||||
signer,
|
signer,
|
||||||
signer2,
|
signer2,
|
||||||
stakeAssetClass,
|
stakeAssetClass,
|
||||||
|
stakeSymbol,
|
||||||
stakeValidator,
|
stakeValidator,
|
||||||
stakeValidatorHash,
|
stakeValidatorHash,
|
||||||
)
|
)
|
||||||
|
|
@ -95,6 +108,7 @@ import Test.Util (
|
||||||
mkMinting,
|
mkMinting,
|
||||||
mkSpending,
|
mkSpending,
|
||||||
sortValue,
|
sortValue,
|
||||||
|
validatorHashes,
|
||||||
)
|
)
|
||||||
|
|
||||||
-- | Parameters for creating a proposal.
|
-- | Parameters for creating a proposal.
|
||||||
|
|
@ -115,11 +129,15 @@ data Parameters = Parameters
|
||||||
-- ^ Is 'TxInfo.validTimeRange' closed?
|
-- ^ Is 'TxInfo.validTimeRange' closed?
|
||||||
, proposalStatus :: ProposalStatus
|
, proposalStatus :: ProposalStatus
|
||||||
-- ^ The status of the newly created proposal.
|
-- ^ 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 :: Integer
|
||||||
maxProposalPerStake = 3
|
maxProposalPerStake = 3
|
||||||
|
|
||||||
|
|
@ -143,7 +161,7 @@ alteredStakeOwner = PubKeyCredential signer2
|
||||||
|
|
||||||
-- | Locks the stake that the input stake already has.
|
-- | Locks the stake that the input stake already has.
|
||||||
defLocks :: [ProposalLock]
|
defLocks :: [ProposalLock]
|
||||||
defLocks = [Created (ProposalId 0)]
|
defLocks = [ProposalLock (ProposalId 0) Created]
|
||||||
|
|
||||||
-- | The effect of the newly created proposal.
|
-- | The effect of the newly created proposal.
|
||||||
defEffects :: StrictMap.Map ResultTag ProposalEffectGroup
|
defEffects :: StrictMap.Map ResultTag ProposalEffectGroup
|
||||||
|
|
@ -164,7 +182,7 @@ governorInputDatum =
|
||||||
, nextProposalId = thisProposalId
|
, nextProposalId = thisProposalId
|
||||||
, proposalTimings = def
|
, proposalTimings = def
|
||||||
, createProposalTimeRangeMaxWidth = def
|
, createProposalTimeRangeMaxWidth = def
|
||||||
, maximumProposalsPerStake = maxProposalPerStake
|
, maximumCreatedProposalsPerStake = maxProposalPerStake
|
||||||
}
|
}
|
||||||
|
|
||||||
-- | Create governor output datum given the parameters.
|
-- | Create governor output datum given the parameters.
|
||||||
|
|
@ -179,7 +197,7 @@ mkGovernorOutputDatum ps =
|
||||||
, nextProposalId = nextPid
|
, nextProposalId = nextPid
|
||||||
, proposalTimings = def
|
, proposalTimings = def
|
||||||
, createProposalTimeRangeMaxWidth = def
|
, createProposalTimeRangeMaxWidth = def
|
||||||
, maximumProposalsPerStake = maxProposalPerStake
|
, maximumCreatedProposalsPerStake = maxProposalPerStake
|
||||||
}
|
}
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
@ -190,7 +208,7 @@ mkStakeInputDatum ps =
|
||||||
let locks =
|
let locks =
|
||||||
if ps.createdMoreThanMaximumProposals
|
if ps.createdMoreThanMaximumProposals
|
||||||
then
|
then
|
||||||
Created . ProposalId
|
flip ProposalLock Created . ProposalId
|
||||||
<$> take
|
<$> take
|
||||||
(fromInteger maxProposalPerStake)
|
(fromInteger maxProposalPerStake)
|
||||||
[1 ..]
|
[1 ..]
|
||||||
|
|
@ -209,10 +227,10 @@ mkStakeOutputDatum ps =
|
||||||
newLocks =
|
newLocks =
|
||||||
if ps.invalidNewLocks
|
if ps.invalidNewLocks
|
||||||
then
|
then
|
||||||
[ Voted thisProposalId (ResultTag 0)
|
[ ProposalLock thisProposalId $ Voted (ResultTag 0) 100
|
||||||
, Voted thisProposalId (ResultTag 1)
|
, ProposalLock thisProposalId $ Voted (ResultTag 1) 100
|
||||||
]
|
]
|
||||||
else [Created thisProposalId]
|
else [ProposalLock thisProposalId Created]
|
||||||
locks = newLocks <> inputDatum.lockedBy
|
locks = newLocks <> inputDatum.lockedBy
|
||||||
newOwner = mkOwner ps
|
newOwner = mkOwner ps
|
||||||
in inputDatum
|
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
|
governorValue = sortValue $ gst <> minAda
|
||||||
stakeValue =
|
stakeValue =
|
||||||
sortValue $
|
sortValue $
|
||||||
|
|
@ -324,7 +366,7 @@ createProposal ps = builder
|
||||||
[ script governorValidatorHash
|
[ script governorValidatorHash
|
||||||
, withValue governorValue
|
, withValue governorValue
|
||||||
, withDatum governorInputDatum
|
, withDatum governorInputDatum
|
||||||
, withRedeemer governorRedeemer
|
, withRedeemer ps.governorRedeemer
|
||||||
, withRef governorRef
|
, withRef governorRef
|
||||||
]
|
]
|
||||||
, output $
|
, output $
|
||||||
|
|
@ -334,19 +376,39 @@ createProposal ps = builder
|
||||||
, withDatum (mkGovernorOutputDatum ps)
|
, withDatum (mkGovernorOutputDatum ps)
|
||||||
]
|
]
|
||||||
, ---
|
, ---
|
||||||
input $
|
if ps.fakeSST
|
||||||
mconcat
|
then
|
||||||
[ script stakeValidatorHash
|
mconcat
|
||||||
, withValue stakeValue
|
[ input @b $
|
||||||
, withDatum (mkStakeInputDatum ps)
|
mconcat
|
||||||
, withRef stakeRef
|
[ script attacker
|
||||||
]
|
, withValue $
|
||||||
, output $
|
Value.singleton
|
||||||
mconcat
|
stakeSymbol
|
||||||
[ script stakeValidatorHash
|
(validatorHashToTokenName attacker)
|
||||||
, withValue stakeValue
|
1
|
||||||
, withDatum (mkStakeOutputDatum ps)
|
, 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 $
|
output $
|
||||||
mconcat
|
mconcat
|
||||||
|
|
@ -354,6 +416,8 @@ createProposal ps = builder
|
||||||
, withValue proposalValue
|
, withValue proposalValue
|
||||||
, withDatum (mkProposalOutputDatum ps)
|
, withDatum (mkProposalOutputDatum ps)
|
||||||
]
|
]
|
||||||
|
, ---
|
||||||
|
fakeStakeBuilder
|
||||||
]
|
]
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
@ -362,10 +426,6 @@ createProposal ps = builder
|
||||||
stakeRedeemer :: StakeRedeemer
|
stakeRedeemer :: StakeRedeemer
|
||||||
stakeRedeemer = PermitVote
|
stakeRedeemer = PermitVote
|
||||||
|
|
||||||
-- | Spend the governor with the 'CreateProposal' redeemer.
|
|
||||||
governorRedeemer :: GovernorRedeemer
|
|
||||||
governorRedeemer = CreateProposal
|
|
||||||
|
|
||||||
-- | Mint the PST with an arbitrary redeemer. Doesn't really matter.
|
-- | Mint the PST with an arbitrary redeemer. Doesn't really matter.
|
||||||
proposalPolicyRedeemer :: ()
|
proposalPolicyRedeemer :: ()
|
||||||
proposalPolicyRedeemer = ()
|
proposalPolicyRedeemer = ()
|
||||||
|
|
@ -383,6 +443,8 @@ totallyValidParameters =
|
||||||
, timeRangeTightEnough = True
|
, timeRangeTightEnough = True
|
||||||
, timeRangeClosed = True
|
, timeRangeClosed = True
|
||||||
, proposalStatus = Draft
|
, proposalStatus = Draft
|
||||||
|
, fakeSST = False
|
||||||
|
, governorRedeemer = Redeemer $ toBuiltinData CreateProposal
|
||||||
}
|
}
|
||||||
|
|
||||||
invalidOutputGovernorDatumParameters :: Parameters
|
invalidOutputGovernorDatumParameters :: Parameters
|
||||||
|
|
@ -435,6 +497,24 @@ invalidProposalStatusParameters =
|
||||||
)
|
)
|
||||||
[VotingReady, Locked, Finished]
|
[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
|
{- | Create a test tree that runs the proposal minting policy, the governor
|
||||||
|
|
@ -467,7 +547,7 @@ mkTestTree
|
||||||
"governor"
|
"governor"
|
||||||
governorValidator
|
governorValidator
|
||||||
governorInputDatum
|
governorInputDatum
|
||||||
governorRedeemer
|
ps.governorRedeemer
|
||||||
(spend governorRef)
|
(spend governorRef)
|
||||||
|
|
||||||
stakeTest =
|
stakeTest =
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,10 @@ import Agora.Proposal.Time (
|
||||||
)
|
)
|
||||||
import Agora.SafeMoney (GTTag)
|
import Agora.SafeMoney (GTTag)
|
||||||
import Agora.Stake (
|
import Agora.Stake (
|
||||||
ProposalLock (
|
ProposalAction (
|
||||||
Voted
|
Voted
|
||||||
),
|
),
|
||||||
|
ProposalLock (ProposalLock),
|
||||||
StakeDatum (..),
|
StakeDatum (..),
|
||||||
StakeRedeemer (PermitVote, RetractVotes),
|
StakeRedeemer (PermitVote, RetractVotes),
|
||||||
)
|
)
|
||||||
|
|
@ -128,8 +129,19 @@ mkStakeInputOutputDatums op =
|
||||||
|
|
||||||
allStakes = take 10 $ firstStake : otherStakes
|
allStakes = take 10 $ firstStake : otherStakes
|
||||||
|
|
||||||
|
createdAt = (def :: ProposalTimingConfig).votingTime - 1
|
||||||
|
|
||||||
stakeWithLock =
|
stakeWithLock =
|
||||||
(\stake -> stake {lockedBy = [Voted defProposalId defResultTag]})
|
( \stake ->
|
||||||
|
stake
|
||||||
|
{ lockedBy =
|
||||||
|
[ ProposalLock defProposalId $
|
||||||
|
Voted
|
||||||
|
defResultTag
|
||||||
|
createdAt
|
||||||
|
]
|
||||||
|
}
|
||||||
|
)
|
||||||
<$> allStakes
|
<$> allStakes
|
||||||
in wrap op (,) allStakes stakeWithLock
|
in wrap op (,) allStakes stakeWithLock
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ module Sample.Proposal.Unlock (
|
||||||
SignedBy (..),
|
SignedBy (..),
|
||||||
TransactionParameters (..),
|
TransactionParameters (..),
|
||||||
ProposalParameters (..),
|
ProposalParameters (..),
|
||||||
|
SSTOwner (..),
|
||||||
StakeParameters (..),
|
StakeParameters (..),
|
||||||
Validity (..),
|
Validity (..),
|
||||||
unlock,
|
unlock,
|
||||||
|
|
@ -26,6 +27,8 @@ module Sample.Proposal.Unlock (
|
||||||
mkRemoveCreatorLockBeforeFinished,
|
mkRemoveCreatorLockBeforeFinished,
|
||||||
mkCreatorRetractVotes,
|
mkCreatorRetractVotes,
|
||||||
mkChangeOutputStakeValue,
|
mkChangeOutputStakeValue,
|
||||||
|
mkUseFakeStakes,
|
||||||
|
mkDisrespectCooldown,
|
||||||
) where
|
) where
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
@ -40,13 +43,18 @@ import Agora.Proposal (
|
||||||
ProposalVotes (..),
|
ProposalVotes (..),
|
||||||
ResultTag (..),
|
ResultTag (..),
|
||||||
)
|
)
|
||||||
import Agora.Proposal.Time (ProposalStartingTime (ProposalStartingTime), ProposalTimingConfig (..))
|
import Agora.Proposal.Time (
|
||||||
|
ProposalStartingTime (ProposalStartingTime),
|
||||||
|
ProposalTimingConfig (..),
|
||||||
|
)
|
||||||
import Agora.SafeMoney (GTTag)
|
import Agora.SafeMoney (GTTag)
|
||||||
import Agora.Stake (
|
import Agora.Stake (
|
||||||
|
ProposalAction (Created, Voted),
|
||||||
ProposalLock (..),
|
ProposalLock (..),
|
||||||
StakeDatum (..),
|
StakeDatum (..),
|
||||||
StakeRedeemer (RetractVotes),
|
StakeRedeemer (RetractVotes),
|
||||||
)
|
)
|
||||||
|
import Data.Coerce (coerce)
|
||||||
import Data.Default.Class (Default (def))
|
import Data.Default.Class (Default (def))
|
||||||
import Data.Map.Strict qualified as StrictMap
|
import Data.Map.Strict qualified as StrictMap
|
||||||
import Data.Tagged (Tagged, untag)
|
import Data.Tagged (Tagged, untag)
|
||||||
|
|
@ -64,8 +72,11 @@ import Plutarch.Context (
|
||||||
withValue,
|
withValue,
|
||||||
)
|
)
|
||||||
import Plutarch.Extra.AssetClass (assetClassValue)
|
import Plutarch.Extra.AssetClass (assetClassValue)
|
||||||
|
import Plutarch.Extra.ScriptContext (validatorHashToTokenName)
|
||||||
|
import PlutusLedgerApi.V1.Value qualified as Value
|
||||||
import PlutusLedgerApi.V2 (
|
import PlutusLedgerApi.V2 (
|
||||||
Credential (PubKeyCredential),
|
Credential (PubKeyCredential),
|
||||||
|
POSIXTime,
|
||||||
PubKeyHash,
|
PubKeyHash,
|
||||||
TxOutRef (..),
|
TxOutRef (..),
|
||||||
)
|
)
|
||||||
|
|
@ -76,7 +87,7 @@ import Sample.Shared (
|
||||||
proposalAssetClass,
|
proposalAssetClass,
|
||||||
proposalValidator,
|
proposalValidator,
|
||||||
proposalValidatorHash,
|
proposalValidatorHash,
|
||||||
stakeAssetClass,
|
stakeSymbol,
|
||||||
stakeValidator,
|
stakeValidator,
|
||||||
stakeValidatorHash,
|
stakeValidatorHash,
|
||||||
)
|
)
|
||||||
|
|
@ -138,7 +149,7 @@ data ParameterBundle = ParameterBundle
|
||||||
|
|
||||||
data SignedBy = Owner | Delegatee | Unknown
|
data SignedBy = Owner | Delegatee | Unknown
|
||||||
|
|
||||||
data TimeRange = WhileVoting | AfterVoting
|
data TimeRange = WhileVoting {offset :: POSIXTime} | AfterVoting
|
||||||
|
|
||||||
data TransactionParameters = TransactionParameters
|
data TransactionParameters = TransactionParameters
|
||||||
{ signedBy :: SignedBy
|
{ signedBy :: SignedBy
|
||||||
|
|
@ -162,12 +173,18 @@ data StakeRole
|
||||||
Irrelevant
|
Irrelevant
|
||||||
deriving stock (Bounded, Enum, Show)
|
deriving stock (Bounded, Enum, Show)
|
||||||
|
|
||||||
|
data SSTOwner
|
||||||
|
= StakeValidator
|
||||||
|
| Attacker
|
||||||
|
|
||||||
data StakeParameters = StakeParameters
|
data StakeParameters = StakeParameters
|
||||||
{ numStakes :: Integer
|
{ numStakes :: Integer
|
||||||
, stakeRole :: StakeRole
|
, stakeRole :: StakeRole
|
||||||
, removeVoterLock :: Bool
|
, removeVoterLock :: Bool
|
||||||
, removeCreatorLock :: Bool
|
, removeCreatorLock :: Bool
|
||||||
, alterOutputValue :: Bool
|
, alterOutputValue :: Bool
|
||||||
|
, sstOwner :: SSTOwner
|
||||||
|
, votingLockCreatedAt :: POSIXTime
|
||||||
}
|
}
|
||||||
|
|
||||||
data Validity = Validity
|
data Validity = Validity
|
||||||
|
|
@ -194,14 +211,20 @@ mkStakeInputDatum ps =
|
||||||
where
|
where
|
||||||
stakeLocks = mkStakeLocks' ps.stakeRole
|
stakeLocks = mkStakeLocks' ps.stakeRole
|
||||||
|
|
||||||
mkStakeLocks' Voter = [Voted defProposalId defVoteFor]
|
mkStakeLocks' Voter =
|
||||||
mkStakeLocks' Creator = [Created defProposalId]
|
[ ProposalLock defProposalId $
|
||||||
|
Voted defVoteFor ps.votingLockCreatedAt
|
||||||
|
]
|
||||||
|
mkStakeLocks' Creator = [ProposalLock defProposalId Created]
|
||||||
mkStakeLocks' Both = mkStakeLocks' Voter <> mkStakeLocks' Creator
|
mkStakeLocks' Both = mkStakeLocks' Voter <> mkStakeLocks' Creator
|
||||||
mkStakeLocks' Irrelevant =
|
mkStakeLocks' Irrelevant =
|
||||||
let ProposalId pid = defProposalId
|
let ProposalId pid = defProposalId
|
||||||
ResultTag vid = defVoteFor
|
ResultTag vid = defVoteFor
|
||||||
in [ Voted (ProposalId $ pid + 1) (ResultTag $ vid + 1)
|
in [ ProposalLock (ProposalId $ pid + 1) $
|
||||||
, Created (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
|
stakeInputDatum = mkStakeInputDatum ps.stakeParameters
|
||||||
|
|
||||||
|
-- TODO respect timing
|
||||||
removeLocks v c =
|
removeLocks v c =
|
||||||
filter $
|
filter $ \(ProposalLock pid action) ->
|
||||||
not
|
pid == defProposalId
|
||||||
. ( \case
|
&& case action of
|
||||||
Created pid -> c && pid == defProposalId
|
Voted _ _ -> v
|
||||||
Cosigned pid -> c && pid == defProposalId
|
_ -> c
|
||||||
Voted pid _ -> v && pid == defProposalId
|
|
||||||
)
|
|
||||||
|
|
||||||
stakeOutputDatum =
|
stakeOutputDatum =
|
||||||
stakeInputDatum
|
stakeInputDatum
|
||||||
|
|
@ -342,9 +368,14 @@ unlock ps = builder
|
||||||
ProposalStartingTime s = defStartingTime
|
ProposalStartingTime s = defStartingTime
|
||||||
|
|
||||||
time = case ps.transactionParameters.timeRange of
|
time = case ps.transactionParameters.timeRange of
|
||||||
WhileVoting ->
|
WhileVoting offset ->
|
||||||
let lb = s + (def :: ProposalTimingConfig).draftTime
|
let lb =
|
||||||
ub = lb + (def :: ProposalTimingConfig).votingTime
|
ps.stakeParameters.votingLockCreatedAt
|
||||||
|
+ offset
|
||||||
|
ub =
|
||||||
|
s
|
||||||
|
+ (def :: ProposalTimingConfig).draftTime
|
||||||
|
+ (def :: ProposalTimingConfig).votingTime
|
||||||
in closedBoundedInterval (lb + 1) (ub - 1)
|
in closedBoundedInterval (lb + 1) (ub - 1)
|
||||||
AfterVoting ->
|
AfterVoting ->
|
||||||
let lb =
|
let lb =
|
||||||
|
|
@ -415,12 +446,22 @@ mkValidVoterRetractVotes i =
|
||||||
, removeVoterLock = True
|
, removeVoterLock = True
|
||||||
, removeCreatorLock = False
|
, removeCreatorLock = False
|
||||||
, alterOutputValue = False
|
, alterOutputValue = False
|
||||||
|
, sstOwner = StakeValidator
|
||||||
|
, votingLockCreatedAt =
|
||||||
|
coerce defStartingTime
|
||||||
|
+ (def :: ProposalTimingConfig).draftTime
|
||||||
|
+ 1
|
||||||
}
|
}
|
||||||
, transactionParameters =
|
, transactionParameters =
|
||||||
TransactionParameters
|
TransactionParameters
|
||||||
{ signedBy = Owner
|
{ signedBy = Owner
|
||||||
, timeRange =
|
, timeRange =
|
||||||
WhileVoting
|
WhileVoting
|
||||||
|
{ offset =
|
||||||
|
coerce
|
||||||
|
(def :: ProposalTimingConfig).minStakeVotingTime
|
||||||
|
+ 5
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -530,10 +571,6 @@ mkCreatorRetractVotes i =
|
||||||
template.stakeParameters
|
template.stakeParameters
|
||||||
{ stakeRole = Creator
|
{ stakeRole = Creator
|
||||||
}
|
}
|
||||||
, transactionParameters =
|
|
||||||
template.transactionParameters
|
|
||||||
{ timeRange = WhileVoting
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mkChangeOutputStakeValue :: Integer -> ParameterBundle
|
mkChangeOutputStakeValue :: Integer -> ParameterBundle
|
||||||
|
|
@ -545,3 +582,29 @@ mkChangeOutputStakeValue i =
|
||||||
{ alterOutputValue = True
|
{ 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ module Sample.Proposal.Vote (
|
||||||
mkTestTree,
|
mkTestTree,
|
||||||
mkValidOwnerVoteBundle,
|
mkValidOwnerVoteBundle,
|
||||||
mkValidDelegateeVoteBundle,
|
mkValidDelegateeVoteBundle,
|
||||||
|
delegateeVoteWithOwnAndDelegatedStakeBundle,
|
||||||
transparentAssets,
|
transparentAssets,
|
||||||
transactionNotAuthorized,
|
transactionNotAuthorized,
|
||||||
voteForNonexistentOutcome,
|
voteForNonexistentOutcome,
|
||||||
|
|
@ -35,6 +36,7 @@ import Agora.Proposal (
|
||||||
ProposalId (ProposalId),
|
ProposalId (ProposalId),
|
||||||
ProposalRedeemer (Vote),
|
ProposalRedeemer (Vote),
|
||||||
ProposalStatus (VotingReady),
|
ProposalStatus (VotingReady),
|
||||||
|
ProposalThresholds (vote),
|
||||||
ProposalVotes (ProposalVotes),
|
ProposalVotes (ProposalVotes),
|
||||||
ResultTag (ResultTag),
|
ResultTag (ResultTag),
|
||||||
)
|
)
|
||||||
|
|
@ -44,7 +46,8 @@ import Agora.Proposal.Time (
|
||||||
)
|
)
|
||||||
import Agora.SafeMoney (GTTag)
|
import Agora.SafeMoney (GTTag)
|
||||||
import Agora.Stake (
|
import Agora.Stake (
|
||||||
ProposalLock (Voted),
|
ProposalAction (Voted),
|
||||||
|
ProposalLock (ProposalLock),
|
||||||
StakeDatum (..),
|
StakeDatum (..),
|
||||||
StakeRedeemer (Destroy, PermitVote),
|
StakeRedeemer (Destroy, PermitVote),
|
||||||
)
|
)
|
||||||
|
|
@ -66,7 +69,7 @@ import Plutarch.Context (
|
||||||
withValue,
|
withValue,
|
||||||
)
|
)
|
||||||
import Plutarch.Extra.AssetClass (adaClass, assetClassValue)
|
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 PlutusLedgerApi.V2.Contexts (TxOutRef (TxOutRef))
|
||||||
import Sample.Proposal.Shared (proposalTxRef)
|
import Sample.Proposal.Shared (proposalTxRef)
|
||||||
import Sample.Shared (
|
import Sample.Shared (
|
||||||
|
|
@ -98,6 +101,7 @@ newtype VoteParameters = VoteParameters {voteFor :: ResultTag}
|
||||||
|
|
||||||
data StakeParameters = StakeParameters
|
data StakeParameters = StakeParameters
|
||||||
{ numStakes :: Integer
|
{ numStakes :: Integer
|
||||||
|
, mixInDelegateeAsOwner :: Bool
|
||||||
, stakeInputParameters :: StakeInputParameters
|
, stakeInputParameters :: StakeInputParameters
|
||||||
, stakeOutputParameters :: StakeOutputParameters
|
, stakeOutputParameters :: StakeOutputParameters
|
||||||
}
|
}
|
||||||
|
|
@ -142,6 +146,24 @@ delegatee = pubKeyHashes !! 1
|
||||||
unknownSig :: PubKeyHash
|
unknownSig :: PubKeyHash
|
||||||
unknownSig = pubKeyHashes !! 2
|
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
|
initialVotes :: StrictMap.Map ResultTag Integer
|
||||||
|
|
@ -194,8 +216,8 @@ mkStakeInputDatum params =
|
||||||
, owner = PubKeyCredential stakeOwner
|
, owner = PubKeyCredential stakeOwner
|
||||||
, delegatedTo = Just (PubKeyCredential delegatee)
|
, delegatedTo = Just (PubKeyCredential delegatee)
|
||||||
, lockedBy =
|
, lockedBy =
|
||||||
[ Voted (ProposalId 0) (ResultTag 0)
|
[ ProposalLock (ProposalId 0) $ Voted (ResultTag 0) 100
|
||||||
, Voted (ProposalId 1) (ResultTag 2)
|
, ProposalLock (ProposalId 1) $ Voted (ResultTag 2) 200
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -224,9 +246,11 @@ vote params =
|
||||||
<> minAda
|
<> minAda
|
||||||
|
|
||||||
newLock =
|
newLock =
|
||||||
Voted
|
ProposalLock
|
||||||
proposalInputDatum.proposalId
|
proposalInputDatum.proposalId
|
||||||
params.voteParameters.voteFor
|
$ Voted
|
||||||
|
params.voteParameters.voteFor
|
||||||
|
validTimeRangeUpperBound
|
||||||
|
|
||||||
updatedLocks =
|
updatedLocks =
|
||||||
if params.stakeParameters.stakeOutputParameters.dontAddNewLock
|
if params.stakeParameters.stakeOutputParameters.dontAddNewLock
|
||||||
|
|
@ -256,6 +280,16 @@ vote params =
|
||||||
stakeRedeemer =
|
stakeRedeemer =
|
||||||
mkStakeRedeemer params.stakeParameters.stakeOutputParameters
|
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 :: b
|
||||||
stakeBuilder =
|
stakeBuilder =
|
||||||
foldMap
|
foldMap
|
||||||
|
|
@ -265,7 +299,7 @@ vote params =
|
||||||
mconcat
|
mconcat
|
||||||
[ script stakeValidatorHash
|
[ script stakeValidatorHash
|
||||||
, withValue stakeInputValue
|
, withValue stakeInputValue
|
||||||
, withInlineDatum stakeInputDatum
|
, withInlineDatum $ mixOwner i stakeInputDatum
|
||||||
, withRedeemer stakeRedeemer
|
, withRedeemer stakeRedeemer
|
||||||
, withRef $ mkStakeRef numProposals' i
|
, withRef $ mkStakeRef numProposals' i
|
||||||
]
|
]
|
||||||
|
|
@ -276,7 +310,7 @@ vote params =
|
||||||
mconcat
|
mconcat
|
||||||
[ script stakeValidatorHash
|
[ script stakeValidatorHash
|
||||||
, withValue stakeOutputValue
|
, 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 :: b
|
||||||
miscBuilder =
|
miscBuilder =
|
||||||
mconcat
|
mconcat
|
||||||
|
|
@ -419,9 +446,10 @@ mkValidOwnerVoteBundle stakes =
|
||||||
, stakeParameters =
|
, stakeParameters =
|
||||||
StakeParameters
|
StakeParameters
|
||||||
{ numStakes = stakes
|
{ numStakes = stakes
|
||||||
|
, mixInDelegateeAsOwner = False
|
||||||
, stakeInputParameters =
|
, stakeInputParameters =
|
||||||
StakeInputParameters
|
StakeInputParameters
|
||||||
{ perStakeGTs = 114514
|
{ perStakeGTs = (def :: ProposalThresholds).vote
|
||||||
}
|
}
|
||||||
, stakeOutputParameters =
|
, stakeOutputParameters =
|
||||||
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 :: ParameterBundle
|
||||||
ownerVoteWithSignleStake = mkValidOwnerVoteBundle 1
|
ownerVoteWithSignleStake = mkValidOwnerVoteBundle 1
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ module Sample.Shared (
|
||||||
signer,
|
signer,
|
||||||
signer2,
|
signer2,
|
||||||
minAda,
|
minAda,
|
||||||
deterministicTracingConfing,
|
deterministicTracingConfig,
|
||||||
mkRedeemer,
|
mkRedeemer,
|
||||||
|
|
||||||
-- * Agora Scripts
|
-- * Agora Scripts
|
||||||
|
|
@ -72,9 +72,6 @@ import Agora.Proposal.Time (
|
||||||
ProposalTimingConfig (..),
|
ProposalTimingConfig (..),
|
||||||
)
|
)
|
||||||
import Agora.SafeMoney (GovernorSTTag, ProposalSTTag, StakeSTTag)
|
import Agora.SafeMoney (GovernorSTTag, ProposalSTTag, StakeSTTag)
|
||||||
import Agora.Utils (
|
|
||||||
validatorHashToTokenName,
|
|
||||||
)
|
|
||||||
import Data.Default.Class (Default (..))
|
import Data.Default.Class (Default (..))
|
||||||
import Data.Map (Map, (!))
|
import Data.Map (Map, (!))
|
||||||
import Data.Tagged (Tagged (..))
|
import Data.Tagged (Tagged (..))
|
||||||
|
|
@ -86,6 +83,7 @@ import Plutarch.Api.V2 (
|
||||||
validatorHash,
|
validatorHash,
|
||||||
)
|
)
|
||||||
import Plutarch.Extra.AssetClass (AssetClass (AssetClass))
|
import Plutarch.Extra.AssetClass (AssetClass (AssetClass))
|
||||||
|
import Plutarch.Extra.ScriptContext (validatorHashToTokenName)
|
||||||
import PlutusLedgerApi.V1.Address (scriptHashAddress)
|
import PlutusLedgerApi.V1.Address (scriptHashAddress)
|
||||||
import PlutusLedgerApi.V1.Value (TokenName, Value)
|
import PlutusLedgerApi.V1.Value (TokenName, Value)
|
||||||
import PlutusLedgerApi.V1.Value qualified as Value (
|
import PlutusLedgerApi.V1.Value qualified as Value (
|
||||||
|
|
@ -123,8 +121,8 @@ import ScriptExport.ScriptInfo (runLinker)
|
||||||
-- Plutarch compiler configauration.
|
-- Plutarch compiler configauration.
|
||||||
-- TODO: add the ability to change this value. Maybe wrap everything in a
|
-- TODO: add the ability to change this value. Maybe wrap everything in a
|
||||||
-- Reader monad?
|
-- Reader monad?
|
||||||
deterministicTracingConfing :: Config
|
deterministicTracingConfig :: Config
|
||||||
deterministicTracingConfing = Config DetTracing
|
deterministicTracingConfig = Config DetTracing
|
||||||
|
|
||||||
governor :: Governor
|
governor :: Governor
|
||||||
governor = Governor oref gt mc
|
governor = Governor oref gt mc
|
||||||
|
|
@ -144,7 +142,7 @@ agoraScripts =
|
||||||
(fmap (view #script) . view #scripts)
|
(fmap (view #script) . view #scripts)
|
||||||
( runLinker
|
( runLinker
|
||||||
linker
|
linker
|
||||||
(Bootstrap.agoraScripts deterministicTracingConfing)
|
(Bootstrap.agoraScripts deterministicTracingConfig)
|
||||||
governor
|
governor
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -242,6 +240,8 @@ instance Default ProposalTimingConfig where
|
||||||
, votingTime = 1000
|
, votingTime = 1000
|
||||||
, lockingTime = 2000
|
, lockingTime = 2000
|
||||||
, executingTime = 3000
|
, executingTime = 3000
|
||||||
|
, minStakeVotingTime = 100
|
||||||
|
, votingTimeRangeMaxWidth = 1000000
|
||||||
}
|
}
|
||||||
|
|
||||||
{- | Default value of 'Agora.Governor.GovernorDatum.createProposalTimeRangeMaxWidth'.
|
{- | Default value of 'Agora.Governor.GovernorDatum.createProposalTimeRangeMaxWidth'.
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,7 @@ module Sample.Stake.Create (
|
||||||
import Agora.Governor (Governor (gtClassRef))
|
import Agora.Governor (Governor (gtClassRef))
|
||||||
import Agora.Proposal (ProposalId (ProposalId))
|
import Agora.Proposal (ProposalId (ProposalId))
|
||||||
import Agora.SafeMoney (GTTag)
|
import Agora.SafeMoney (GTTag)
|
||||||
import Agora.Stake (ProposalLock (Created), StakeDatum (..))
|
import Agora.Stake (ProposalAction (Created), ProposalLock (ProposalLock), StakeDatum (..))
|
||||||
import Agora.Utils (validatorHashToTokenName)
|
|
||||||
import Data.Semigroup (stimesMonoid)
|
import Data.Semigroup (stimesMonoid)
|
||||||
import Data.Tagged (Tagged)
|
import Data.Tagged (Tagged)
|
||||||
import Plutarch.Context (
|
import Plutarch.Context (
|
||||||
|
|
@ -36,6 +35,7 @@ import Plutarch.Context (
|
||||||
withValue,
|
withValue,
|
||||||
)
|
)
|
||||||
import Plutarch.Extra.AssetClass (assetClassValue)
|
import Plutarch.Extra.AssetClass (assetClassValue)
|
||||||
|
import Plutarch.Extra.ScriptContext (validatorHashToTokenName)
|
||||||
import Plutarch.Lift (PUnsafeLiftDecl (PLifted))
|
import Plutarch.Lift (PUnsafeLiftDecl (PLifted))
|
||||||
import PlutusLedgerApi.V1.Value qualified as Value
|
import PlutusLedgerApi.V1.Value qualified as Value
|
||||||
import PlutusLedgerApi.V2 (
|
import PlutusLedgerApi.V2 (
|
||||||
|
|
@ -255,6 +255,6 @@ alreadyHasLocks =
|
||||||
{ stakedAmount = 114514
|
{ stakedAmount = 114514
|
||||||
, owner = PubKeyCredential signer
|
, owner = PubKeyCredential signer
|
||||||
, delegatedTo = Nothing
|
, delegatedTo = Nothing
|
||||||
, lockedBy = [Created $ ProposalId 0]
|
, lockedBy = [ProposalLock (ProposalId 0) Created]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,8 @@ module Sample.Stake.Destroy (
|
||||||
|
|
||||||
import Agora.Proposal (ProposalId (..))
|
import Agora.Proposal (ProposalId (..))
|
||||||
import Agora.Stake (
|
import Agora.Stake (
|
||||||
ProposalLock (Created),
|
ProposalAction (Created),
|
||||||
|
ProposalLock (ProposalLock),
|
||||||
StakeDatum (..),
|
StakeDatum (..),
|
||||||
StakeRedeemer (Destroy),
|
StakeRedeemer (Destroy),
|
||||||
)
|
)
|
||||||
|
|
@ -105,7 +106,7 @@ mkStakeInputDatum ps =
|
||||||
{ stakedAmount = 114514
|
{ stakedAmount = 114514
|
||||||
, owner = PubKeyCredential owner
|
, owner = PubKeyCredential owner
|
||||||
, delegatedTo = Just $ PubKeyCredential delegatee
|
, delegatedTo = Just $ PubKeyCredential delegatee
|
||||||
, lockedBy = [Created $ ProposalId 0 | ps.notUnlocked]
|
, lockedBy = [ProposalLock (ProposalId 0) Created | ps.notUnlocked]
|
||||||
}
|
}
|
||||||
|
|
||||||
mkStakeRef :: Int -> TxOutRef
|
mkStakeRef :: Int -> TxOutRef
|
||||||
|
|
|
||||||
74
agora-specs/Sample/Stake/UnauthorizedMintingExploit.hs
Normal file
74
agora-specs/Sample/Stake/UnauthorizedMintingExploit.hs
Normal file
|
|
@ -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
|
||||||
|
|
@ -10,7 +10,7 @@ Tests for Authority token functions
|
||||||
module Spec.AuthorityToken (specs) where
|
module Spec.AuthorityToken (specs) where
|
||||||
|
|
||||||
import Agora.AuthorityToken (singleAuthorityTokenBurned)
|
import Agora.AuthorityToken (singleAuthorityTokenBurned)
|
||||||
import Plutarch (ClosedTerm, POpaque, perror, popaque)
|
import Data.Tagged (Tagged (Tagged))
|
||||||
import Plutarch.Extra.Compile (mustCompile)
|
import Plutarch.Extra.Compile (mustCompile)
|
||||||
import Plutarch.Unsafe (punsafeCoerce)
|
import Plutarch.Unsafe (punsafeCoerce)
|
||||||
import PlutusLedgerApi.V1 (
|
import PlutusLedgerApi.V1 (
|
||||||
|
|
@ -29,21 +29,13 @@ import PlutusLedgerApi.V1.Value qualified as Value (
|
||||||
singleton,
|
singleton,
|
||||||
)
|
)
|
||||||
import PlutusTx.AssocMap qualified as AssocMap (empty)
|
import PlutusTx.AssocMap qualified as AssocMap (empty)
|
||||||
|
import Sample.AuthorityToken.UnauthorizedMintingExploit qualified as UnauthorizedMintingExploit
|
||||||
import Test.Specification (
|
import Test.Specification (
|
||||||
SpecificationTree,
|
SpecificationTree,
|
||||||
group,
|
group,
|
||||||
scriptFails,
|
scriptFails,
|
||||||
scriptSucceeds,
|
scriptSucceeds,
|
||||||
)
|
)
|
||||||
import Prelude (
|
|
||||||
Maybe (Nothing),
|
|
||||||
PBool,
|
|
||||||
Semigroup ((<>)),
|
|
||||||
fmap,
|
|
||||||
pconstant,
|
|
||||||
pif,
|
|
||||||
($),
|
|
||||||
)
|
|
||||||
|
|
||||||
currencySymbol :: CurrencySymbol
|
currencySymbol :: CurrencySymbol
|
||||||
currencySymbol = "deadbeef"
|
currencySymbol = "deadbeef"
|
||||||
|
|
@ -54,7 +46,7 @@ mkInputs = fmap (TxInInfo (TxOutRef "" 0))
|
||||||
singleAuthorityTokenBurnedTest :: Value -> [TxOut] -> Script
|
singleAuthorityTokenBurnedTest :: Value -> [TxOut] -> Script
|
||||||
singleAuthorityTokenBurnedTest mint outs =
|
singleAuthorityTokenBurnedTest mint outs =
|
||||||
let actual :: ClosedTerm PBool
|
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 :: ClosedTerm POpaque
|
||||||
s =
|
s =
|
||||||
pif
|
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
|
||||||
|
]
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,24 @@ specs =
|
||||||
True
|
True
|
||||||
)
|
)
|
||||||
Create.invalidProposalStatusParameters
|
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
|
, group
|
||||||
|
|
@ -148,6 +166,10 @@ specs =
|
||||||
"transparent non-GT tokens"
|
"transparent non-GT tokens"
|
||||||
Vote.transparentAssets
|
Vote.transparentAssets
|
||||||
(Vote.Validity True True)
|
(Vote.Validity True True)
|
||||||
|
, Vote.mkTestTree
|
||||||
|
"Delegatee vote with own and delegated stakes in one tx"
|
||||||
|
Vote.delegateeVoteWithOwnAndDelegatedStakeBundle
|
||||||
|
(Vote.Validity True True)
|
||||||
]
|
]
|
||||||
, group
|
, group
|
||||||
"illegal"
|
"illegal"
|
||||||
|
|
@ -327,6 +349,25 @@ specs =
|
||||||
, forGovernorValidator = Just False
|
, forGovernorValidator = Just False
|
||||||
, forAuthorityTokenPolicy = Just True
|
, 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" $
|
, group "unlocking" $
|
||||||
|
|
@ -392,6 +433,14 @@ specs =
|
||||||
"change output stake value"
|
"change output stake value"
|
||||||
(Unlock.mkChangeOutputStakeValue nStakes)
|
(Unlock.mkChangeOutputStakeValue nStakes)
|
||||||
(Unlock.Validity True False)
|
(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
|
legalGroup = group "legal" $ map mkLegalGroup stakeCountCases
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ import Sample.Stake qualified as Stake (
|
||||||
import Sample.Stake.Create qualified as Create
|
import Sample.Stake.Create qualified as Create
|
||||||
import Sample.Stake.Destroy qualified as Destroy
|
import Sample.Stake.Destroy qualified as Destroy
|
||||||
import Sample.Stake.SetDelegate qualified as SetDelegate
|
import Sample.Stake.SetDelegate qualified as SetDelegate
|
||||||
|
import Sample.Stake.UnauthorizedMintingExploit qualified as UnauthorizedMintingExploit
|
||||||
import Test.Specification (
|
import Test.Specification (
|
||||||
SpecificationTree,
|
SpecificationTree,
|
||||||
group,
|
group,
|
||||||
|
|
@ -179,5 +180,13 @@ specs =
|
||||||
SetDelegate.invalidOutputStakeDatumParameters
|
SetDelegate.invalidOutputStakeDatumParameters
|
||||||
False
|
False
|
||||||
]
|
]
|
||||||
|
, group
|
||||||
|
"unauthorized SST minting exploit"
|
||||||
|
$ map
|
||||||
|
( UnauthorizedMintingExploit.mkTestCase
|
||||||
|
"(negative test)"
|
||||||
|
. UnauthorizedMintingExploit.Parameters
|
||||||
|
)
|
||||||
|
[1 .. 20]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -143,6 +143,9 @@ common test-deps
|
||||||
common exe-opts
|
common exe-opts
|
||||||
ghc-options: -threaded -rtsopts -with-rtsopts=-N -O0
|
ghc-options: -threaded -rtsopts -with-rtsopts=-N -O0
|
||||||
|
|
||||||
|
common test-opts
|
||||||
|
ghc-options: -threaded -rtsopts -with-rtsopts=-N -O2
|
||||||
|
|
||||||
library
|
library
|
||||||
import: lang, deps, plutarch-prelude
|
import: lang, deps, plutarch-prelude
|
||||||
exposed-modules:
|
exposed-modules:
|
||||||
|
|
@ -192,6 +195,7 @@ library agora-specs
|
||||||
exposed-modules:
|
exposed-modules:
|
||||||
Property.Generator
|
Property.Generator
|
||||||
Property.Governor
|
Property.Governor
|
||||||
|
Sample.AuthorityToken.UnauthorizedMintingExploit
|
||||||
Sample.Effect.GovernorMutation
|
Sample.Effect.GovernorMutation
|
||||||
Sample.Effect.TreasuryWithdrawal
|
Sample.Effect.TreasuryWithdrawal
|
||||||
Sample.Governor.Initialize
|
Sample.Governor.Initialize
|
||||||
|
|
@ -208,6 +212,7 @@ library agora-specs
|
||||||
Sample.Stake.Create
|
Sample.Stake.Create
|
||||||
Sample.Stake.Destroy
|
Sample.Stake.Destroy
|
||||||
Sample.Stake.SetDelegate
|
Sample.Stake.SetDelegate
|
||||||
|
Sample.Stake.UnauthorizedMintingExploit
|
||||||
Sample.Treasury
|
Sample.Treasury
|
||||||
Spec.AuthorityToken
|
Spec.AuthorityToken
|
||||||
Spec.Effect.GovernorMutation
|
Spec.Effect.GovernorMutation
|
||||||
|
|
@ -222,7 +227,7 @@ library agora-specs
|
||||||
build-depends: agora-testlib
|
build-depends: agora-testlib
|
||||||
|
|
||||||
test-suite agora-test
|
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
|
type: exitcode-stdio-1.0
|
||||||
main-is: Spec.hs
|
main-is: Spec.hs
|
||||||
hs-source-dirs: agora-test
|
hs-source-dirs: agora-test
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,9 @@ module Agora.AuthorityToken (
|
||||||
singleAuthorityTokenBurned,
|
singleAuthorityTokenBurned,
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Agora.Utils (
|
import Agora.Governor (PGovernorRedeemer (PMintGATs), presolveGovernorRedeemer)
|
||||||
passert,
|
import Agora.SafeMoney (AuthorityTokenTag, GovernorSTTag)
|
||||||
psymbolValueOf',
|
import Agora.Utils (ptag, ptaggedSymbolValueOf, ptoScottEncodingT, puntag)
|
||||||
)
|
|
||||||
import Plutarch.Api.V1 (
|
import Plutarch.Api.V1 (
|
||||||
PCredential (..),
|
PCredential (..),
|
||||||
PCurrencySymbol (..),
|
PCurrencySymbol (..),
|
||||||
|
|
@ -26,17 +25,16 @@ import Plutarch.Api.V2 (
|
||||||
KeyGuarantees,
|
KeyGuarantees,
|
||||||
PAddress (PAddress),
|
PAddress (PAddress),
|
||||||
PMintingPolicy,
|
PMintingPolicy,
|
||||||
PScriptContext (PScriptContext),
|
|
||||||
PScriptPurpose (PMinting),
|
PScriptPurpose (PMinting),
|
||||||
PTxInInfo (PTxInInfo),
|
PTxInInfo (PTxInInfo),
|
||||||
PTxInfo (PTxInfo),
|
|
||||||
PTxOut (PTxOut),
|
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 "liqwid-plutarch-extra" Plutarch.Extra.List (plookupAssoc)
|
||||||
import Plutarch.Extra.Maybe (pfromJust)
|
import Plutarch.Extra.Maybe (passertPJust, pfromJust)
|
||||||
import Plutarch.Extra.ScriptContext (pisTokenSpent)
|
|
||||||
import Plutarch.Extra.Sum (PSum (PSum))
|
import Plutarch.Extra.Sum (PSum (PSum))
|
||||||
|
import Plutarch.Extra.Tagged (PTagged)
|
||||||
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (
|
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (
|
||||||
pguardC,
|
pguardC,
|
||||||
pletC,
|
pletC,
|
||||||
|
|
@ -44,7 +42,7 @@ import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (
|
||||||
pmatchC,
|
pmatchC,
|
||||||
)
|
)
|
||||||
import Plutarch.Extra.Traversable (pfoldMap)
|
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
|
@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 $
|
authorityTokensValidIn = phoistAcyclic $
|
||||||
plam $ \authorityTokenSym txOut'' -> unTermCont $ do
|
plam $ \authorityTokenSym txOut'' -> unTermCont $ do
|
||||||
PTxOut txOut' <- pmatchC txOut''
|
PTxOut txOut' <- pmatchC txOut''
|
||||||
|
|
@ -75,7 +73,7 @@ authorityTokensValidIn = phoistAcyclic $
|
||||||
PValue value' <- pmatchC txOut.value
|
PValue value' <- pmatchC txOut.value
|
||||||
PMap value <- pmatchC value'
|
PMap value <- pmatchC value'
|
||||||
pure $
|
pure $
|
||||||
pmatch (plookupAssoc # pfstBuiltin # psndBuiltin # pdata authorityTokenSym # value) $ \case
|
pmatch (plookupAssoc # pfstBuiltin # psndBuiltin # pdata (puntag authorityTokenSym) # value) $ \case
|
||||||
PJust (pfromData -> _tokenMap') ->
|
PJust (pfromData -> _tokenMap') ->
|
||||||
pmatch (pfield @"credential" # address) $ \case
|
pmatch (pfield @"credential" # address) $ \case
|
||||||
PPubKeyCredential _ ->
|
PPubKeyCredential _ ->
|
||||||
|
|
@ -97,13 +95,13 @@ authorityTokensValidIn = phoistAcyclic $
|
||||||
-}
|
-}
|
||||||
singleAuthorityTokenBurned ::
|
singleAuthorityTokenBurned ::
|
||||||
forall (keys :: KeyGuarantees) (amounts :: AmountGuarantees) (s :: S).
|
forall (keys :: KeyGuarantees) (amounts :: AmountGuarantees) (s :: S).
|
||||||
Term s PCurrencySymbol ->
|
Term s (PTagged AuthorityTokenTag PCurrencySymbol) ->
|
||||||
Term s (PBuiltinList PTxInInfo) ->
|
Term s (PBuiltinList PTxInInfo) ->
|
||||||
Term s (PValue keys amounts) ->
|
Term s (PValue keys amounts) ->
|
||||||
Term s PBool
|
Term s PBool
|
||||||
singleAuthorityTokenBurned gatCs inputs mint = unTermCont $ do
|
singleAuthorityTokenBurned gatCs inputs mint = unTermCont $ do
|
||||||
let gatAmountMinted :: Term _ PInteger
|
let gatAmountMinted :: Term _ PInteger
|
||||||
gatAmountMinted = psymbolValueOf # gatCs # mint
|
gatAmountMinted = ptaggedSymbolValueOf # gatCs # mint
|
||||||
|
|
||||||
let inputsWithGAT =
|
let inputsWithGAT =
|
||||||
pfoldMap
|
pfoldMap
|
||||||
|
|
@ -119,12 +117,13 @@ singleAuthorityTokenBurned gatCs inputs mint = unTermCont $ do
|
||||||
$ resolved
|
$ resolved
|
||||||
|
|
||||||
pure . pcon . PSum $
|
pure . pcon . PSum $
|
||||||
psymbolValueOf
|
ptaggedSymbolValueOf
|
||||||
# gatCs
|
# gatCs
|
||||||
#$ pfield @"value"
|
#$ pfield @"value"
|
||||||
#$ resolved
|
#$ resolved
|
||||||
)
|
)
|
||||||
# inputs
|
# inputs
|
||||||
|
|
||||||
pure $
|
pure $
|
||||||
foldr1
|
foldr1
|
||||||
(#&&)
|
(#&&)
|
||||||
|
|
@ -147,35 +146,46 @@ singleAuthorityTokenBurned gatCs inputs mint = unTermCont $ do
|
||||||
|
|
||||||
@since 0.1.0
|
@since 0.1.0
|
||||||
-}
|
-}
|
||||||
authorityTokenPolicy :: ClosedTerm (PAssetClassData :--> PMintingPolicy)
|
authorityTokenPolicy :: ClosedTerm (PTagged GovernorSTTag PAssetClassData :--> PMintingPolicy)
|
||||||
authorityTokenPolicy =
|
authorityTokenPolicy =
|
||||||
plam $ \atAssetClass _redeemer ctx' ->
|
plam $ \gstAssetClass _redeemer ctx -> unTermCont $ do
|
||||||
pmatch ctx' $ \(PScriptContext ctx') -> unTermCont $ do
|
ctxF <- pletFieldsC @'["txInfo", "purpose"] ctx
|
||||||
ctx <- pletFieldsC @'["txInfo", "purpose"] ctx'
|
txInfoF <-
|
||||||
PTxInfo txInfo' <- pmatchC $ pfromData ctx.txInfo
|
pletFieldsC
|
||||||
txInfo <- pletFieldsC @'["inputs", "mint", "outputs"] txInfo'
|
@'[ "inputs"
|
||||||
let inputs = txInfo.inputs
|
, "mint"
|
||||||
govTokenSpent = pisTokenSpent # (ptoScottEncoding # atAssetClass) # inputs
|
, "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 <-
|
PPair mintedATs burntATs <-
|
||||||
pmatchC $ pfromJust #$ psymbolValueOf' # ownSymbol # txInfo.mint
|
pmatchC $ pfromJust #$ psymbolValueOf' # ownSymbol # txInfoF.mint
|
||||||
|
|
||||||
pure $
|
pure $
|
||||||
popaque $
|
popaque $
|
||||||
pif
|
pif
|
||||||
(0 #< mintedATs)
|
(0 #< mintedATs)
|
||||||
( unTermCont $ do
|
( unTermCont $ do
|
||||||
pguardC "No GAT burnt" $ 0 #== burntATs
|
pguardC "No GAT burnt" $ 0 #== burntATs
|
||||||
pguardC "Parent token did not move in minting GATs" govTokenSpent
|
let governorRedeemer =
|
||||||
pguardC "All outputs only emit valid GATs" $
|
passertPJust
|
||||||
pall
|
# "GST should move"
|
||||||
# plam
|
#$ presolveGovernorRedeemer
|
||||||
(authorityTokensValidIn # ownSymbol #)
|
# (ptoScottEncodingT # gstAssetClass)
|
||||||
# txInfo.outputs
|
# pfromData txInfoF.inputs
|
||||||
pure $ pconstant ()
|
# txInfoF.redeemers
|
||||||
)
|
pguardC "Governor redeemr correct" $
|
||||||
(passert "No GAT minted" (0 #== mintedATs) (pconstant ()))
|
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 ()))
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ Helpers for constructing effects.
|
||||||
module Agora.Effect (makeEffect) where
|
module Agora.Effect (makeEffect) where
|
||||||
|
|
||||||
import Agora.AuthorityToken (singleAuthorityTokenBurned)
|
import Agora.AuthorityToken (singleAuthorityTokenBurned)
|
||||||
|
import Agora.SafeMoney (AuthorityTokenTag)
|
||||||
import Plutarch.Api.V1 (
|
import Plutarch.Api.V1 (
|
||||||
PCurrencySymbol,
|
PCurrencySymbol,
|
||||||
)
|
)
|
||||||
|
|
@ -17,6 +18,7 @@ import Plutarch.Api.V2 (
|
||||||
PTxOutRef,
|
PTxOutRef,
|
||||||
PValidator,
|
PValidator,
|
||||||
)
|
)
|
||||||
|
import Plutarch.Extra.Tagged (PTagged)
|
||||||
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pguardC, pletC, pletFieldsC, pmatchC, ptryFromC)
|
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pguardC, pletC, pletFieldsC, pmatchC, ptryFromC)
|
||||||
|
|
||||||
{- | Helper "template" for creating effect validator.
|
{- | Helper "template" for creating effect validator.
|
||||||
|
|
@ -30,13 +32,13 @@ import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pguardC, pletC, pletFiel
|
||||||
makeEffect ::
|
makeEffect ::
|
||||||
forall (datum :: PType) (s :: S).
|
forall (datum :: PType) (s :: S).
|
||||||
(PTryFrom PData datum, PIsData datum) =>
|
(PTryFrom PData datum, PIsData datum) =>
|
||||||
( Term s PCurrencySymbol ->
|
( Term s (PTagged AuthorityTokenTag PCurrencySymbol) ->
|
||||||
Term s datum ->
|
Term s datum ->
|
||||||
Term s PTxOutRef ->
|
Term s PTxOutRef ->
|
||||||
Term s (PAsData PTxInfo) ->
|
Term s (PAsData PTxInfo) ->
|
||||||
Term s POpaque
|
Term s POpaque
|
||||||
) ->
|
) ->
|
||||||
Term s PCurrencySymbol ->
|
Term s (PTagged AuthorityTokenTag PCurrencySymbol) ->
|
||||||
Term s PValidator
|
Term s PValidator
|
||||||
makeEffect f atSymbol =
|
makeEffect f atSymbol =
|
||||||
plam $ \datum _redeemer ctx' -> unTermCont $ do
|
plam $ \datum _redeemer ctx' -> unTermCont $ do
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,8 @@ import Agora.Governor (
|
||||||
PGovernorDatum,
|
PGovernorDatum,
|
||||||
PGovernorRedeemer,
|
PGovernorRedeemer,
|
||||||
)
|
)
|
||||||
import Agora.Plutarch.Orphans ()
|
import Agora.SafeMoney (AuthorityTokenTag, GovernorSTTag)
|
||||||
import Agora.Utils (pfromSingleton, ptryFromRedeemer)
|
import Agora.Utils (ptaggedSymbolValueOf)
|
||||||
import Plutarch.Api.V1 (PCurrencySymbol, PValidatorHash)
|
import Plutarch.Api.V1 (PCurrencySymbol, PValidatorHash)
|
||||||
import Plutarch.Api.V2 (
|
import Plutarch.Api.V2 (
|
||||||
PScriptPurpose (PSpending),
|
PScriptPurpose (PSpending),
|
||||||
|
|
@ -38,11 +38,17 @@ import Plutarch.DataRepr (
|
||||||
PDataFields,
|
PDataFields,
|
||||||
)
|
)
|
||||||
import Plutarch.Extra.Field (pletAll, pletAllC)
|
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.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 "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pguardC, pletC, pletFieldsC)
|
||||||
import Plutarch.Extra.Value (psymbolValueOf)
|
|
||||||
import Plutarch.Lift (PConstantDecl, PLifted, PUnsafeLiftDecl)
|
import Plutarch.Lift (PConstantDecl, PLifted, PUnsafeLiftDecl)
|
||||||
import PlutusLedgerApi.V1 (TxOutRef)
|
import PlutusLedgerApi.V1 (TxOutRef)
|
||||||
import PlutusTx qualified
|
import PlutusTx qualified
|
||||||
|
|
@ -145,8 +151,8 @@ deriving anyclass instance PTryFrom PData PMutateGovernorDatum
|
||||||
mutateGovernorValidator ::
|
mutateGovernorValidator ::
|
||||||
ClosedTerm
|
ClosedTerm
|
||||||
( PValidatorHash
|
( PValidatorHash
|
||||||
:--> PCurrencySymbol
|
:--> PTagged GovernorSTTag PCurrencySymbol
|
||||||
:--> PCurrencySymbol
|
:--> PTagged AuthorityTokenTag PCurrencySymbol
|
||||||
:--> PValidator
|
:--> PValidator
|
||||||
)
|
)
|
||||||
mutateGovernorValidator =
|
mutateGovernorValidator =
|
||||||
|
|
@ -177,25 +183,23 @@ mutateGovernorValidator =
|
||||||
pany
|
pany
|
||||||
# plam
|
# plam
|
||||||
( flip pletAll $ \inputF ->
|
( flip pletAll $ \inputF ->
|
||||||
let governorAddress =
|
let isGovernorInput =
|
||||||
paddressFromValidatorHash
|
|
||||||
# govValidatorHash
|
|
||||||
# pdnothing
|
|
||||||
|
|
||||||
isGovernorInput =
|
|
||||||
foldl1
|
foldl1
|
||||||
(#&&)
|
(#&&)
|
||||||
[ ptraceIfFalse "Governor UTxO should carry GST" $
|
[ ptraceIfFalse "Governor UTxO should carry GST" $
|
||||||
psymbolValueOf
|
ptaggedSymbolValueOf
|
||||||
# gstSymbol
|
# gstSymbol
|
||||||
# (pfield @"value" # inputF.resolved)
|
# (pfield @"value" # inputF.resolved)
|
||||||
#== 1
|
#== 1
|
||||||
, ptraceIfFalse "Can only modify the pinned governor" $
|
, ptraceIfFalse "Can only modify the pinned governor" $
|
||||||
inputF.outRef #== effectDatumF.governorRef
|
inputF.outRef #== effectDatumF.governorRef
|
||||||
, ptraceIfFalse "Governor validator run" $
|
, ptraceIfFalse "Governor validator run" $
|
||||||
pfield @"address"
|
let inputValidatorHash =
|
||||||
# inputF.resolved
|
pfromJust
|
||||||
#== governorAddress
|
#$ pvalidatorHashFromAddress
|
||||||
|
#$ pfield @"address"
|
||||||
|
# inputF.resolved
|
||||||
|
in inputValidatorHash #== govValidatorHash
|
||||||
]
|
]
|
||||||
in isGovernorInput
|
in isGovernorInput
|
||||||
)
|
)
|
||||||
|
|
@ -216,11 +220,11 @@ mutateGovernorValidator =
|
||||||
|
|
||||||
let governorOutput =
|
let governorOutput =
|
||||||
ptrace "Only governor output is allowed" $
|
ptrace "Only governor output is allowed" $
|
||||||
pfromSingleton # pfromData txInfoF.outputs
|
ptryFromSingleton # pfromData txInfoF.outputs
|
||||||
|
|
||||||
governorOutputDatum =
|
governorOutputDatum =
|
||||||
ptrace "Resolve governor outoput datum" $
|
ptrace "Resolve governor outoput datum" $
|
||||||
pfromOutputDatum @PGovernorDatum
|
ptryFromOutputDatum @PGovernorDatum
|
||||||
# (pfield @"datum" # governorOutput)
|
# (pfield @"datum" # governorOutput)
|
||||||
# txInfoF.datums
|
# txInfoF.datums
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,10 @@ A dumb effect that only burns its GAT.
|
||||||
module Agora.Effect.NoOp (noOpValidator, PNoOp) where
|
module Agora.Effect.NoOp (noOpValidator, PNoOp) where
|
||||||
|
|
||||||
import Agora.Effect (makeEffect)
|
import Agora.Effect (makeEffect)
|
||||||
import Agora.Plutarch.Orphans ()
|
import Agora.SafeMoney (AuthorityTokenTag)
|
||||||
import Plutarch.Api.V1 (PCurrencySymbol)
|
import Plutarch.Api.V1 (PCurrencySymbol)
|
||||||
import Plutarch.Api.V2 (PValidator)
|
import Plutarch.Api.V2 (PValidator)
|
||||||
import Plutarch.Orphans ()
|
import Plutarch.Extra.Tagged (PTagged)
|
||||||
|
|
||||||
{- | Dummy datum for NoOp effect.
|
{- | Dummy datum for NoOp effect.
|
||||||
|
|
||||||
|
|
@ -40,7 +40,7 @@ instance PTryFrom PData (PAsData PNoOp)
|
||||||
|
|
||||||
@since 1.0.0
|
@since 1.0.0
|
||||||
-}
|
-}
|
||||||
noOpValidator :: ClosedTerm (PCurrencySymbol :--> PValidator)
|
noOpValidator :: ClosedTerm (PTagged AuthorityTokenTag PCurrencySymbol :--> PValidator)
|
||||||
noOpValidator = plam $
|
noOpValidator = plam $
|
||||||
makeEffect $
|
makeEffect $
|
||||||
\_ (_datum :: Term s (PAsData PNoOp)) _ _ -> popaque (pconstant ())
|
\_ (_datum :: Term s (PAsData PNoOp)) _ _ -> popaque (pconstant ())
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,7 @@ module Agora.Effect.TreasuryWithdrawal (
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Agora.Effect (makeEffect)
|
import Agora.Effect (makeEffect)
|
||||||
import Agora.Plutarch.Orphans ()
|
import Agora.SafeMoney (AuthorityTokenTag)
|
||||||
import Agora.Utils (pdelete)
|
|
||||||
import Plutarch.Api.V1 (
|
import Plutarch.Api.V1 (
|
||||||
PCredential,
|
PCredential,
|
||||||
PCurrencySymbol,
|
PCurrencySymbol,
|
||||||
|
|
@ -35,7 +34,9 @@ import Plutarch.DataRepr (
|
||||||
PDataFields,
|
PDataFields,
|
||||||
)
|
)
|
||||||
import Plutarch.Extra.Field (pletAllC)
|
import Plutarch.Extra.Field (pletAllC)
|
||||||
|
import "liqwid-plutarch-extra" Plutarch.Extra.List (pdeleteFirst)
|
||||||
import Plutarch.Extra.ScriptContext (pisPubKey)
|
import Plutarch.Extra.ScriptContext (pisPubKey)
|
||||||
|
import Plutarch.Extra.Tagged (PTagged)
|
||||||
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pguardC, pletC, pletFieldsC)
|
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pguardC, pletC, pletFieldsC)
|
||||||
import Plutarch.Lift (PConstantDecl, PUnsafeLiftDecl (PLifted))
|
import Plutarch.Lift (PConstantDecl, PUnsafeLiftDecl (PLifted))
|
||||||
import PlutusLedgerApi.V1.Credential (Credential)
|
import PlutusLedgerApi.V1.Credential (Credential)
|
||||||
|
|
@ -133,7 +134,7 @@ instance PTryFrom PData PTreasuryWithdrawalDatum
|
||||||
-}
|
-}
|
||||||
treasuryWithdrawalValidator ::
|
treasuryWithdrawalValidator ::
|
||||||
forall (s :: S).
|
forall (s :: S).
|
||||||
Term s (PCurrencySymbol :--> PValidator)
|
Term s (PTagged AuthorityTokenTag PCurrencySymbol :--> PValidator)
|
||||||
treasuryWithdrawalValidator = plam $
|
treasuryWithdrawalValidator = plam $
|
||||||
makeEffect $
|
makeEffect $
|
||||||
\_cs (datum :: Term _ PTreasuryWithdrawalDatum) effectInputRef txInfo -> unTermCont $ do
|
\_cs (datum :: Term _ PTreasuryWithdrawalDatum) effectInputRef txInfo -> unTermCont $ do
|
||||||
|
|
@ -178,7 +179,7 @@ treasuryWithdrawalValidator = plam $
|
||||||
(ptraceError "Invalid receiver")
|
(ptraceError "Invalid receiver")
|
||||||
|
|
||||||
pure $
|
pure $
|
||||||
pmatch (pdelete # credValue # receivers) $ \case
|
pmatch (pdeleteFirst # credValue # receivers) $ \case
|
||||||
PJust updatedReceivers ->
|
PJust updatedReceivers ->
|
||||||
ptrace "Receiver output" updatedReceivers
|
ptrace "Receiver output" updatedReceivers
|
||||||
PNothing ->
|
PNothing ->
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ module Agora.Governor (
|
||||||
pgetNextProposalId,
|
pgetNextProposalId,
|
||||||
getNextProposalId,
|
getNextProposalId,
|
||||||
pisGovernorDatumValid,
|
pisGovernorDatumValid,
|
||||||
|
presolveGovernorRedeemer,
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Agora.Aeson.Orphans ()
|
import Agora.Aeson.Orphans ()
|
||||||
|
|
@ -39,20 +40,33 @@ import Agora.Proposal.Time (
|
||||||
pisMaxTimeRangeWidthValid,
|
pisMaxTimeRangeWidthValid,
|
||||||
pisProposalTimingConfigValid,
|
pisProposalTimingConfigValid,
|
||||||
)
|
)
|
||||||
import Agora.SafeMoney (GTTag)
|
import Agora.SafeMoney (GTTag, GovernorSTTag)
|
||||||
import Data.Aeson qualified as Aeson
|
import Data.Aeson qualified as Aeson
|
||||||
import Data.Tagged (Tagged)
|
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 (
|
import Plutarch.DataRepr (
|
||||||
DerivePConstantViaData (DerivePConstantViaData),
|
DerivePConstantViaData (DerivePConstantViaData),
|
||||||
PDataFields,
|
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 (
|
import Plutarch.Extra.IsData (
|
||||||
DerivePConstantViaEnum (DerivePConstantEnum),
|
DerivePConstantViaEnum (DerivePConstantEnum),
|
||||||
EnumIsData (EnumIsData),
|
EnumIsData (EnumIsData),
|
||||||
PlutusTypeEnumData,
|
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 "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pletFieldsC)
|
||||||
|
import Plutarch.Extra.Value (passetClassValueOfT)
|
||||||
import Plutarch.Lift (PConstantDecl, PUnsafeLiftDecl (PLifted))
|
import Plutarch.Lift (PConstantDecl, PUnsafeLiftDecl (PLifted))
|
||||||
import PlutusLedgerApi.V1 (TxOutRef)
|
import PlutusLedgerApi.V1 (TxOutRef)
|
||||||
import PlutusTx qualified
|
import PlutusTx qualified
|
||||||
|
|
@ -73,9 +87,8 @@ data GovernorDatum = GovernorDatum
|
||||||
-- Will get copied over upon the creation of proposals.
|
-- Will get copied over upon the creation of proposals.
|
||||||
, createProposalTimeRangeMaxWidth :: MaxTimeRangeWidth
|
, createProposalTimeRangeMaxWidth :: MaxTimeRangeWidth
|
||||||
-- ^ The maximum valid duration of a transaction that creats a proposal.
|
-- ^ The maximum valid duration of a transaction that creats a proposal.
|
||||||
, maximumProposalsPerStake :: Integer
|
, maximumCreatedProposalsPerStake :: Integer
|
||||||
-- ^ The maximum number of unfinished proposals that a stake is allowed to be
|
-- ^ The maximum number of proposals created by any given stakes.
|
||||||
-- associated to.
|
|
||||||
}
|
}
|
||||||
deriving stock
|
deriving stock
|
||||||
( -- | @since 0.1.0
|
( -- | @since 0.1.0
|
||||||
|
|
@ -84,6 +97,9 @@ data GovernorDatum = GovernorDatum
|
||||||
Generic
|
Generic
|
||||||
)
|
)
|
||||||
|
|
||||||
|
-- | @since 0.2.1
|
||||||
|
makeFieldLabelsNoPrefix ''GovernorDatum
|
||||||
|
|
||||||
-- | @since 0.1.0
|
-- | @since 0.1.0
|
||||||
PlutusTx.makeIsDataIndexed ''GovernorDatum [('GovernorDatum, 0)]
|
PlutusTx.makeIsDataIndexed ''GovernorDatum [('GovernorDatum, 0)]
|
||||||
|
|
||||||
|
|
@ -149,6 +165,8 @@ data Governor = Governor
|
||||||
Aeson.FromJSON
|
Aeson.FromJSON
|
||||||
)
|
)
|
||||||
|
|
||||||
|
makeFieldLabelsNoPrefix ''Governor
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
{- | Plutarch-level datum for the Governor script.
|
{- | Plutarch-level datum for the Governor script.
|
||||||
|
|
@ -164,7 +182,7 @@ newtype PGovernorDatum (s :: S) = PGovernorDatum
|
||||||
, "nextProposalId" ':= PProposalId
|
, "nextProposalId" ':= PProposalId
|
||||||
, "proposalTimings" ':= PProposalTimingConfig
|
, "proposalTimings" ':= PProposalTimingConfig
|
||||||
, "createProposalTimeRangeMaxWidth" ':= PMaxTimeRangeWidth
|
, "createProposalTimeRangeMaxWidth" ':= PMaxTimeRangeWidth
|
||||||
, "maximumProposalsPerStake" ':= PInteger
|
, "maximumCreatedProposalsPerStake" ':= PInteger
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -181,6 +199,8 @@ newtype PGovernorDatum (s :: S) = PGovernorDatum
|
||||||
PDataFields
|
PDataFields
|
||||||
, -- | @since 0.1.0
|
, -- | @since 0.1.0
|
||||||
PEq
|
PEq
|
||||||
|
, -- | @since 0.2.1
|
||||||
|
PShow
|
||||||
)
|
)
|
||||||
|
|
||||||
-- | @since 0.2.0
|
-- | @since 0.2.0
|
||||||
|
|
@ -277,3 +297,53 @@ pisGovernorDatumValid = phoistAcyclic $
|
||||||
, ptraceIfFalse "time range valid" $
|
, ptraceIfFalse "time range valid" $
|
||||||
pisMaxTimeRangeWidthValid # datumF.createProposalTimeRangeMaxWidth
|
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
|
||||||
|
|
|
||||||
|
|
@ -35,41 +35,42 @@ import Agora.Proposal (
|
||||||
pneutralOption,
|
pneutralOption,
|
||||||
pwinner,
|
pwinner,
|
||||||
)
|
)
|
||||||
import Agora.Proposal.Time (validateProposalStartingTime)
|
import Agora.Proposal.Time (pvalidateProposalStartingTime)
|
||||||
|
import Agora.SafeMoney (AuthorityTokenTag, GovernorSTTag, ProposalSTTag, StakeSTTag)
|
||||||
import Agora.Stake (
|
import Agora.Stake (
|
||||||
pnumCreatedProposals,
|
pnumCreatedProposals,
|
||||||
presolveStakeInputDatum,
|
presolveStakeInputDatum,
|
||||||
)
|
)
|
||||||
import Agora.Utils (
|
import Agora.Utils (ptaggedSymbolValueOf, ptoScottEncodingT, puntag)
|
||||||
plistEqualsBy,
|
import Data.Function (on)
|
||||||
pscriptHashToTokenName,
|
import Plutarch.Api.V1 (PCurrencySymbol, PValidatorHash)
|
||||||
)
|
|
||||||
import Plutarch.Api.V1 (PCurrencySymbol)
|
|
||||||
import Plutarch.Api.V1.AssocMap (plookup)
|
import Plutarch.Api.V1.AssocMap (plookup)
|
||||||
import Plutarch.Api.V1.AssocMap qualified as AssocMap
|
import Plutarch.Api.V1.AssocMap qualified as AssocMap
|
||||||
import Plutarch.Api.V2 (
|
import Plutarch.Api.V2 (
|
||||||
PAddress,
|
|
||||||
PMintingPolicy,
|
PMintingPolicy,
|
||||||
PScriptPurpose (PMinting, PSpending),
|
PScriptPurpose (PMinting, PSpending),
|
||||||
PTxOut,
|
PTxOut,
|
||||||
PTxOutRef,
|
PTxOutRef,
|
||||||
PValidator,
|
PValidator,
|
||||||
)
|
)
|
||||||
import Plutarch.Extra.AssetClass (PAssetClassData, passetClass, ptoScottEncoding)
|
import Plutarch.Extra.AssetClass (PAssetClassData, passetClass)
|
||||||
import Plutarch.Extra.Field (pletAll, pletAllC)
|
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 "liqwid-plutarch-extra" Plutarch.Extra.Map (pkeys, ptryLookup)
|
||||||
import Plutarch.Extra.Maybe (passertPJust, pjust, pmaybe, pmaybeData, pnothing)
|
import Plutarch.Extra.Maybe (passertPJust, pfromJust, pjust, pmaybeData, pnothing)
|
||||||
import Plutarch.Extra.Ord (psort)
|
import Plutarch.Extra.Ord (POrdering (..), pcompareBy, pfromOrd, psort)
|
||||||
import Plutarch.Extra.Record (mkRecordConstr, (.&), (.=))
|
import Plutarch.Extra.Record (mkRecordConstr, (.&), (.=))
|
||||||
import Plutarch.Extra.ScriptContext (
|
import Plutarch.Extra.ScriptContext (
|
||||||
pfindTxInByTxOutRef,
|
pfindTxInByTxOutRef,
|
||||||
pfromDatumHash,
|
|
||||||
pfromOutputDatum,
|
|
||||||
pisUTXOSpent,
|
pisUTXOSpent,
|
||||||
pscriptHashFromAddress,
|
pscriptHashFromAddress,
|
||||||
|
pscriptHashToTokenName,
|
||||||
|
ptryFromDatumHash,
|
||||||
|
ptryFromOutputDatum,
|
||||||
|
pvalidatorHashFromAddress,
|
||||||
pvalueSpent,
|
pvalueSpent,
|
||||||
)
|
)
|
||||||
|
import Plutarch.Extra.Tagged (PTagged)
|
||||||
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (
|
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (
|
||||||
pguardC,
|
pguardC,
|
||||||
pletC,
|
pletC,
|
||||||
|
|
@ -153,7 +154,7 @@ governorPolicy =
|
||||||
|
|
||||||
governorDatum =
|
governorDatum =
|
||||||
ptrace "Resolve governor datum" $
|
ptrace "Resolve governor datum" $
|
||||||
pfromOutputDatum @PGovernorDatum
|
ptryFromOutputDatum @PGovernorDatum
|
||||||
# txOutF.datum
|
# txOutF.datum
|
||||||
# txInfoF.datums
|
# txInfoF.datums
|
||||||
in pif isGovernorUTxO (pjust # governorDatum) pnothing
|
in pif isGovernorUTxO (pjust # governorDatum) pnothing
|
||||||
|
|
@ -263,15 +264,15 @@ governorPolicy =
|
||||||
governorValidator ::
|
governorValidator ::
|
||||||
-- | Lazy precompiled scripts.
|
-- | Lazy precompiled scripts.
|
||||||
ClosedTerm
|
ClosedTerm
|
||||||
( PAddress
|
( PValidatorHash
|
||||||
:--> PAssetClassData
|
:--> PTagged StakeSTTag PAssetClassData
|
||||||
:--> PCurrencySymbol
|
:--> PTagged GovernorSTTag PCurrencySymbol
|
||||||
:--> PCurrencySymbol
|
:--> PTagged ProposalSTTag PCurrencySymbol
|
||||||
:--> PCurrencySymbol
|
:--> PTagged AuthorityTokenTag PCurrencySymbol
|
||||||
:--> PValidator
|
:--> PValidator
|
||||||
)
|
)
|
||||||
governorValidator =
|
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
|
ctxF <- pletAllC ctx
|
||||||
txInfo <- pletC $ pfromData ctxF.txInfo
|
txInfo <- pletC $ pfromData ctxF.txInfo
|
||||||
txInfoF <-
|
txInfoF <-
|
||||||
|
|
@ -316,14 +317,16 @@ governorValidator =
|
||||||
foldl1
|
foldl1
|
||||||
(#&&)
|
(#&&)
|
||||||
[ ptraceIfFalse "Own by governor validator" $
|
[ ptraceIfFalse "Own by governor validator" $
|
||||||
outputF.address #== governorInputF.address
|
((#==) `on` (pvalidatorHashFromAddress #))
|
||||||
|
outputF.address
|
||||||
|
governorInputF.address
|
||||||
, ptraceIfFalse "Has governor ST" $
|
, ptraceIfFalse "Has governor ST" $
|
||||||
psymbolValueOf # gstSymbol # outputF.value #== 1
|
ptaggedSymbolValueOf # gstSymbol # outputF.value #== 1
|
||||||
]
|
]
|
||||||
|
|
||||||
datum =
|
datum =
|
||||||
ptrace "Resolve governor datum" $
|
ptrace "Resolve governor datum" $
|
||||||
pfromOutputDatum @PGovernorDatum
|
ptryFromOutputDatum @PGovernorDatum
|
||||||
# outputF.datum
|
# outputF.datum
|
||||||
# txInfoF.datums
|
# txInfoF.datums
|
||||||
in pif
|
in pif
|
||||||
|
|
@ -335,22 +338,24 @@ governorValidator =
|
||||||
|
|
||||||
----------------------------------------------------------------------------
|
----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
pstClass <- pletC $ passetClass # pto pstSymbol # pconstant ""
|
||||||
|
|
||||||
getProposalDatum :: Term _ (PTxOut :--> PMaybe PProposalDatum) <-
|
getProposalDatum :: Term _ (PTxOut :--> PMaybe PProposalDatum) <-
|
||||||
pletC $
|
pletC $
|
||||||
plam $
|
plam $
|
||||||
flip (pletFields @'["value", "datum", "address"]) $ \txOutF ->
|
flip (pletFields @'["value", "datum", "address"]) $ \txOutF ->
|
||||||
let isProposalUTxO =
|
let isProposalUTxO =
|
||||||
txOutF.address
|
(pfromJust #$ pvalidatorHashFromAddress # pfromData txOutF.address)
|
||||||
#== pdata proposalValidatorAddress
|
#== proposalValidatorHash
|
||||||
#&& psymbolValueOf
|
#&& passetClassValueOf
|
||||||
# pstSymbol
|
# pstClass
|
||||||
# txOutF.value
|
# txOutF.value
|
||||||
#== 1
|
#== 1
|
||||||
|
|
||||||
proposalDatum =
|
proposalDatum =
|
||||||
ptrace "Resolve proposal output datum" $
|
ptrace "Resolve proposal output datum" $
|
||||||
pfromData $
|
pfromData $
|
||||||
pfromOutputDatum
|
ptryFromOutputDatum
|
||||||
# txOutF.datum
|
# txOutF.datum
|
||||||
# txInfoF.datums
|
# txInfoF.datums
|
||||||
in pif isProposalUTxO (pjust # proposalDatum) pnothing
|
in pif isProposalUTxO (pjust # proposalDatum) pnothing
|
||||||
|
|
@ -378,8 +383,8 @@ governorValidator =
|
||||||
.= governorInputDatumF.proposalTimings
|
.= governorInputDatumF.proposalTimings
|
||||||
.& #createProposalTimeRangeMaxWidth
|
.& #createProposalTimeRangeMaxWidth
|
||||||
.= governorInputDatumF.createProposalTimeRangeMaxWidth
|
.= governorInputDatumF.createProposalTimeRangeMaxWidth
|
||||||
.& #maximumProposalsPerStake
|
.& #maximumCreatedProposalsPerStake
|
||||||
.= governorInputDatumF.maximumProposalsPerStake
|
.= governorInputDatumF.maximumCreatedProposalsPerStake
|
||||||
)
|
)
|
||||||
|
|
||||||
pguardC "Only next proposal id gets advanced" $
|
pguardC "Only next proposal id gets advanced" $
|
||||||
|
|
@ -388,16 +393,7 @@ governorValidator =
|
||||||
-- Check that exactly one proposal token is being minted.
|
-- Check that exactly one proposal token is being minted.
|
||||||
|
|
||||||
pguardC "Exactly one proposal token must be minted" $
|
pguardC "Exactly one proposal token must be minted" $
|
||||||
let vMap = pfromData $ pto txInfoF.mint
|
passetClassValueOf # pstClass # txInfoF.mint #== 1
|
||||||
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
|
|
||||||
|
|
||||||
-- Check that a stake is spent to create the propsal,
|
-- Check that a stake is spent to create the propsal,
|
||||||
-- and the value it contains meets the requirement.
|
-- and the value it contains meets the requirement.
|
||||||
|
|
@ -407,7 +403,7 @@ governorValidator =
|
||||||
# "Stake input should present"
|
# "Stake input should present"
|
||||||
#$ pfindJust
|
#$ pfindJust
|
||||||
# ( presolveStakeInputDatum
|
# ( presolveStakeInputDatum
|
||||||
# (ptoScottEncoding # sstClass)
|
# (ptoScottEncodingT # sstClass)
|
||||||
# txInfoF.datums
|
# txInfoF.datums
|
||||||
)
|
)
|
||||||
# pfromData txInfoF.inputs
|
# pfromData txInfoF.inputs
|
||||||
|
|
@ -417,7 +413,7 @@ governorValidator =
|
||||||
pguardC "Proposals created by the stake must not exceed the limit" $
|
pguardC "Proposals created by the stake must not exceed the limit" $
|
||||||
pnumCreatedProposals
|
pnumCreatedProposals
|
||||||
# stakeInputDatumF.lockedBy
|
# stakeInputDatumF.lockedBy
|
||||||
#< governorInputDatumF.maximumProposalsPerStake
|
#< governorInputDatumF.maximumCreatedProposalsPerStake
|
||||||
|
|
||||||
let gtThreshold =
|
let gtThreshold =
|
||||||
pfromData $
|
pfromData $
|
||||||
|
|
@ -425,7 +421,7 @@ governorValidator =
|
||||||
# governorInputDatumF.proposalThresholds
|
# governorInputDatumF.proposalThresholds
|
||||||
|
|
||||||
pguardC "Require minimum amount of GTs" $
|
pguardC "Require minimum amount of GTs" $
|
||||||
gtThreshold #< stakeInputDatumF.stakedAmount
|
gtThreshold #<= stakeInputDatumF.stakedAmount
|
||||||
|
|
||||||
-- Check that the newly minted PST is sent to the proposal validator,
|
-- Check that the newly minted PST is sent to the proposal validator,
|
||||||
-- and the datum it carries is legal.
|
-- and the datum it carries is legal.
|
||||||
|
|
@ -457,7 +453,7 @@ governorValidator =
|
||||||
, ptraceIfFalse "cosigners correct" $
|
, ptraceIfFalse "cosigners correct" $
|
||||||
plistEquals # pfromData proposalOutputDatumF.cosigners # expectedCosigners
|
plistEquals # pfromData proposalOutputDatumF.cosigners # expectedCosigners
|
||||||
, ptraceIfFalse "starting time valid" $
|
, ptraceIfFalse "starting time valid" $
|
||||||
validateProposalStartingTime
|
pvalidateProposalStartingTime
|
||||||
# governorInputDatumF.createProposalTimeRangeMaxWidth
|
# governorInputDatumF.createProposalTimeRangeMaxWidth
|
||||||
# txInfoF.validRange
|
# txInfoF.validRange
|
||||||
# proposalOutputDatumF.startingTime
|
# proposalOutputDatumF.startingTime
|
||||||
|
|
@ -478,7 +474,7 @@ governorValidator =
|
||||||
-- Filter out proposal inputs and ouputs using PST and the address of proposal validator.
|
-- 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" $
|
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 =
|
let proposalInputDatum =
|
||||||
passertPJust
|
passertPJust
|
||||||
|
|
@ -510,14 +506,13 @@ governorValidator =
|
||||||
( \output -> unTermCont $ do
|
( \output -> unTermCont $ do
|
||||||
outputF <- pletFieldsC @'["address", "datum", "value"] output
|
outputF <- pletFieldsC @'["address", "datum", "value"] output
|
||||||
|
|
||||||
let isAuthorityUTxO =
|
let atAmount =
|
||||||
psymbolValueOf
|
ptaggedSymbolValueOf
|
||||||
# atSymbol
|
# atSymbol
|
||||||
# outputF.value
|
# outputF.value
|
||||||
#== 1
|
|
||||||
|
|
||||||
handleAuthorityUTxO =
|
handleAuthorityUTxO =
|
||||||
unTermCont $ do
|
do
|
||||||
receiverScriptHash <-
|
receiverScriptHash <-
|
||||||
pletC $
|
pletC $
|
||||||
passertPJust
|
passertPJust
|
||||||
|
|
@ -538,7 +533,7 @@ governorValidator =
|
||||||
# pconstant ""
|
# pconstant ""
|
||||||
# plam (pscriptHashToTokenName . pfromData)
|
# plam (pscriptHashToTokenName . pfromData)
|
||||||
# effect.scriptHash
|
# effect.scriptHash
|
||||||
gatAssetClass = passetClass # atSymbol # tagToken
|
gatAssetClass = passetClass # puntag atSymbol # tagToken
|
||||||
valueGATCorrect =
|
valueGATCorrect =
|
||||||
passetClassValueOf
|
passetClassValueOf
|
||||||
# gatAssetClass
|
# gatAssetClass
|
||||||
|
|
@ -546,7 +541,7 @@ governorValidator =
|
||||||
#== 1
|
#== 1
|
||||||
|
|
||||||
let hasCorrectDatum =
|
let hasCorrectDatum =
|
||||||
effect.datumHash #== pfromDatumHash # outputF.datum
|
effect.datumHash #== ptryFromDatumHash # outputF.datum
|
||||||
|
|
||||||
pguardC "Authority output valid" $
|
pguardC "Authority output valid" $
|
||||||
foldr1
|
foldr1
|
||||||
|
|
@ -556,19 +551,27 @@ governorValidator =
|
||||||
, ptraceIfFalse "Value correctly encodes Auth Check script" valueGATCorrect
|
, ptraceIfFalse "Value correctly encodes Auth Check script" valueGATCorrect
|
||||||
]
|
]
|
||||||
|
|
||||||
pure receiverScriptHash
|
pure $ pjust # receiverScriptHash
|
||||||
|
|
||||||
pure $
|
pmatchC
|
||||||
pif
|
( pcompareBy
|
||||||
isAuthorityUTxO
|
# pfromOrd
|
||||||
(pjust # handleAuthorityUTxO)
|
# atAmount
|
||||||
pnothing
|
# 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.
|
-- The sorted hashes of all the GAT receivers.
|
||||||
actualReceivers =
|
actualReceivers =
|
||||||
psort
|
psort
|
||||||
#$ pmapMaybe
|
#$ pmapMaybe @PList
|
||||||
# getReceiverScriptHash
|
# getReceiverScriptHash
|
||||||
# pfromData txInfoF.outputs
|
# pfromData txInfoF.outputs
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,14 @@
|
||||||
module Agora.Linker (linker, AgoraScriptInfo (..)) where
|
module Agora.Linker (linker, AgoraScriptInfo (..)) where
|
||||||
|
|
||||||
import Agora.Governor (Governor (gstOutRef, gtClassRef, maximumCosigners))
|
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.Aeson qualified as Aeson
|
||||||
import Data.Map (fromList)
|
import Data.Map (fromList)
|
||||||
import Data.Tagged (untag)
|
import Data.Tagged (Tagged (Tagged))
|
||||||
import Plutarch.Api.V2 (mintingPolicySymbol, validatorHash)
|
import Plutarch.Api.V2 (mintingPolicySymbol, validatorHash)
|
||||||
import Plutarch.Extra.AssetClass (AssetClass (AssetClass))
|
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 (
|
import Ply (
|
||||||
ScriptRole (MintingPolicyRole, ValidatorRole),
|
ScriptRole (MintingPolicyRole, ValidatorRole),
|
||||||
toMintingPolicy,
|
toMintingPolicy,
|
||||||
|
|
@ -30,10 +31,10 @@ import Prelude hiding ((#))
|
||||||
@since 1.0.0
|
@since 1.0.0
|
||||||
-}
|
-}
|
||||||
data AgoraScriptInfo = AgoraScriptInfo
|
data AgoraScriptInfo = AgoraScriptInfo
|
||||||
{ governorAssetClass :: AssetClass
|
{ governorAssetClass :: Tagged GovernorSTTag AssetClass
|
||||||
, authorityTokenSymbol :: CurrencySymbol
|
, authorityTokenSymbol :: Tagged AuthorityTokenTag CurrencySymbol
|
||||||
, proposalAssetClass :: AssetClass
|
, proposalAssetClass :: Tagged ProposalSTTag AssetClass
|
||||||
, stakeAssetClass :: AssetClass
|
, stakeAssetClass :: Tagged StakeSTTag AssetClass
|
||||||
, governor :: Governor
|
, governor :: Governor
|
||||||
}
|
}
|
||||||
deriving stock (Generic, Show)
|
deriving stock (Generic, Show)
|
||||||
|
|
@ -45,28 +46,86 @@ data AgoraScriptInfo = AgoraScriptInfo
|
||||||
-}
|
-}
|
||||||
linker :: Linker Governor (ScriptExport AgoraScriptInfo)
|
linker :: Linker Governor (ScriptExport AgoraScriptInfo)
|
||||||
linker = do
|
linker = do
|
||||||
govPol <- fetchTS @MintingPolicyRole @'[TxOutRef] "agora:governorPolicy"
|
govPol <-
|
||||||
govVal <- fetchTS @ValidatorRole @'[Address, AssetClass, CurrencySymbol, CurrencySymbol, CurrencySymbol] "agora:governorValidator"
|
fetchTS
|
||||||
stkPol <- fetchTS @MintingPolicyRole @'[AssetClass] "agora:stakePolicy"
|
@MintingPolicyRole
|
||||||
stkVal <- fetchTS @ValidatorRole @'[CurrencySymbol, AssetClass, AssetClass] "agora:stakeValidator"
|
@'[TxOutRef]
|
||||||
prpPol <- fetchTS @MintingPolicyRole @'[AssetClass] "agora:proposalPolicy"
|
"agora:governorPolicy"
|
||||||
prpVal <- fetchTS @ValidatorRole @'[AssetClass, CurrencySymbol, CurrencySymbol, Integer] "agora:proposalValidator"
|
govVal <-
|
||||||
treVal <- fetchTS @ValidatorRole @'[CurrencySymbol] "agora:treasuryValidator"
|
fetchTS
|
||||||
atkPol <- fetchTS @MintingPolicyRole @'[AssetClass] "agora:authorityTokenPolicy"
|
@ValidatorRole
|
||||||
noOpVal <- fetchTS @ValidatorRole @'[CurrencySymbol] "agora:noOpValidator"
|
@'[ ValidatorHash
|
||||||
treaWithdrawalVal <- fetchTS @ValidatorRole @'[CurrencySymbol] "agora:treasuryWithdrawalValidator"
|
, Tagged StakeSTTag AssetClass
|
||||||
mutateGovVal <- fetchTS @ValidatorRole @'[ValidatorHash, CurrencySymbol, CurrencySymbol] "agora:mutateGovernorValidator"
|
, 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
|
governor <- getParam
|
||||||
|
|
||||||
let govPol' = govPol # governor.gstOutRef
|
let govPol' = govPol # governor.gstOutRef
|
||||||
govVal' =
|
govVal' =
|
||||||
govVal
|
govVal
|
||||||
# propValAddress
|
# propValHash
|
||||||
# sstAssetClass
|
# Tagged sstAssetClass
|
||||||
# gstSymbol
|
# Tagged gstSymbol
|
||||||
# pstSymbol
|
# Tagged pstSymbol
|
||||||
# atSymbol
|
# Tagged atSymbol
|
||||||
gstSymbol =
|
gstSymbol =
|
||||||
mintingPolicySymbol $
|
mintingPolicySymbol $
|
||||||
toMintingPolicy
|
toMintingPolicy
|
||||||
|
|
@ -75,34 +134,40 @@ linker = do
|
||||||
AssetClass gstSymbol ""
|
AssetClass gstSymbol ""
|
||||||
govValHash = validatorHash $ toValidator govVal'
|
govValHash = validatorHash $ toValidator govVal'
|
||||||
|
|
||||||
at = gstAssetClass
|
atPol' = atkPol # Tagged gstAssetClass
|
||||||
atPol' = atkPol # at
|
|
||||||
atSymbol = mintingPolicySymbol $ toMintingPolicy atPol'
|
atSymbol = mintingPolicySymbol $ toMintingPolicy atPol'
|
||||||
|
|
||||||
propPol' = prpPol # gstAssetClass
|
propPol' = prpPol # Tagged gstAssetClass
|
||||||
propVal' =
|
propVal' =
|
||||||
prpVal
|
prpVal
|
||||||
# sstAssetClass
|
# Tagged sstAssetClass
|
||||||
# gstSymbol
|
# Tagged gstSymbol
|
||||||
# pstSymbol
|
# Tagged pstSymbol
|
||||||
# governor.maximumCosigners
|
# governor.maximumCosigners
|
||||||
propValAddress =
|
propValHash = validatorHash $ toValidator propVal'
|
||||||
validatorHashToAddress $ validatorHash $ toValidator propVal'
|
|
||||||
pstSymbol = mintingPolicySymbol $ toMintingPolicy propPol'
|
pstSymbol = mintingPolicySymbol $ toMintingPolicy propPol'
|
||||||
pstAssetClass = AssetClass pstSymbol ""
|
pstAssetClass = AssetClass pstSymbol ""
|
||||||
|
|
||||||
stakPol' = stkPol # untag governor.gtClassRef
|
stakPol' = stkPol # governor.gtClassRef
|
||||||
stakVal' = stkVal # sstSymbol # pstAssetClass # untag governor.gtClassRef
|
stakVal' =
|
||||||
|
stkVal
|
||||||
|
# Tagged sstSymbol
|
||||||
|
# Tagged pstAssetClass
|
||||||
|
# governor.gtClassRef
|
||||||
sstSymbol = mintingPolicySymbol $ toMintingPolicy stakPol'
|
sstSymbol = mintingPolicySymbol $ toMintingPolicy stakPol'
|
||||||
stakValTokenName =
|
stakValTokenName =
|
||||||
validatorHashToTokenName $ validatorHash $ toValidator stakVal'
|
validatorHashToTokenName $ validatorHash $ toValidator stakVal'
|
||||||
sstAssetClass = AssetClass sstSymbol stakValTokenName
|
sstAssetClass = AssetClass sstSymbol stakValTokenName
|
||||||
|
|
||||||
treaVal' = treVal # atSymbol
|
treaVal' = treVal # Tagged atSymbol
|
||||||
|
|
||||||
noOpVal' = noOpVal # atSymbol
|
noOpVal' = noOpVal # Tagged atSymbol
|
||||||
treaWithdrawalVal' = treaWithdrawalVal # atSymbol
|
treaWithdrawalVal' = treaWithdrawalVal # Tagged atSymbol
|
||||||
mutateGovVal' = mutateGovVal # govValHash # gstSymbol # atSymbol
|
mutateGovVal' =
|
||||||
|
mutateGovVal
|
||||||
|
# govValHash
|
||||||
|
# Tagged gstSymbol
|
||||||
|
# Tagged atSymbol
|
||||||
|
|
||||||
return $
|
return $
|
||||||
ScriptExport
|
ScriptExport
|
||||||
|
|
@ -122,10 +187,10 @@ linker = do
|
||||||
]
|
]
|
||||||
, information =
|
, information =
|
||||||
AgoraScriptInfo
|
AgoraScriptInfo
|
||||||
{ governorAssetClass = gstAssetClass
|
{ governorAssetClass = Tagged gstAssetClass
|
||||||
, authorityTokenSymbol = atSymbol
|
, authorityTokenSymbol = Tagged atSymbol
|
||||||
, proposalAssetClass = pstAssetClass
|
, proposalAssetClass = Tagged pstAssetClass
|
||||||
, stakeAssetClass = sstAssetClass
|
, stakeAssetClass = Tagged sstAssetClass
|
||||||
, governor = governor
|
, governor = governor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,14 @@ import Plutarch.Lift (PConstantDecl (..), PUnsafeLiftDecl (PLifted))
|
||||||
|
|
||||||
import Data.Bifunctor (Bifunctor (bimap))
|
import Data.Bifunctor (Bifunctor (bimap))
|
||||||
import Data.Map.Strict qualified as StrictMap
|
import Data.Map.Strict qualified as StrictMap
|
||||||
|
import Data.Tagged (Tagged (Tagged))
|
||||||
import Data.Traversable (for)
|
import Data.Traversable (for)
|
||||||
import Plutarch.Api.V1 (KeyGuarantees (Sorted), PMap)
|
import Plutarch.Api.V1 (KeyGuarantees (Sorted), PMap)
|
||||||
|
import Plutarch.Extra.Tagged (PTagged)
|
||||||
import PlutusTx qualified
|
import PlutusTx qualified
|
||||||
import PlutusTx.AssocMap qualified as AssocMap
|
import PlutusTx.AssocMap qualified as AssocMap
|
||||||
|
import Ply (PlyArg)
|
||||||
|
import Ply.Plutarch.Class (PlyArgOf)
|
||||||
|
|
||||||
-- | @since 1.0.0
|
-- | @since 1.0.0
|
||||||
instance
|
instance
|
||||||
|
|
@ -74,3 +78,9 @@ instance
|
||||||
isSorted [] = True
|
isSorted [] = True
|
||||||
isSorted [_] = True
|
isSorted [_] = True
|
||||||
isSorted (x : y : xs) = x < y && isSorted (y : xs)
|
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)
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,7 @@ newtype ResultTag = ResultTag {getResultTag :: Integer}
|
||||||
data ProposalStatus
|
data ProposalStatus
|
||||||
= -- | A draft proposal represents a proposal that has yet to be realized.
|
= -- | 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
|
-- proposal, and needs cosigners to enable that to happen. This is
|
||||||
-- similar to a "temperature check", but only useful if multiple people
|
-- similar to a "temperature check", but only useful if multiple people
|
||||||
-- want to pool governance tokens together. If the proposal doesn't get to
|
-- want to pool governance tokens together. If the proposal doesn't get to
|
||||||
|
|
@ -579,6 +579,8 @@ newtype PProposalThresholds (s :: S) = PProposalThresholds
|
||||||
PIsData
|
PIsData
|
||||||
, -- | @since 0.1.0
|
, -- | @since 0.1.0
|
||||||
PDataFields
|
PDataFields
|
||||||
|
, -- | @since 0.2.1
|
||||||
|
PShow
|
||||||
)
|
)
|
||||||
|
|
||||||
-- | @since 0.2.0
|
-- | @since 0.2.0
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ module Agora.Proposal.Scripts (
|
||||||
proposalPolicy,
|
proposalPolicy,
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Agora.Governor (PGovernorRedeemer (PCreateProposal))
|
import Agora.Governor (PGovernorRedeemer (PCreateProposal), presolveGovernorRedeemer)
|
||||||
import Agora.Proposal (
|
import Agora.Proposal (
|
||||||
PProposalDatum (PProposalDatum),
|
PProposalDatum (PProposalDatum),
|
||||||
PProposalRedeemer (PAdvanceProposal, PCosign, PUnlockStake, PVote),
|
PProposalRedeemer (PAdvanceProposal, PCosign, PUnlockStake, PVote),
|
||||||
|
|
@ -23,10 +23,12 @@ import Agora.Proposal (
|
||||||
import Agora.Proposal.Time (
|
import Agora.Proposal.Time (
|
||||||
PPeriod (PDraftingPeriod, PExecutingPeriod, PLockingPeriod, PVotingPeriod),
|
PPeriod (PDraftingPeriod, PExecutingPeriod, PLockingPeriod, PVotingPeriod),
|
||||||
PTimingRelation (PAfter, PWithin),
|
PTimingRelation (PAfter, PWithin),
|
||||||
currentProposalTime,
|
pcurrentProposalTime,
|
||||||
pgetRelation,
|
pgetRelation,
|
||||||
pisWithin,
|
pisWithin,
|
||||||
|
psatisfyMaximumWidth,
|
||||||
)
|
)
|
||||||
|
import Agora.SafeMoney (GovernorSTTag, ProposalSTTag, StakeSTTag)
|
||||||
import Agora.Stake (
|
import Agora.Stake (
|
||||||
PStakeDatum,
|
PStakeDatum,
|
||||||
pextractVoteOption,
|
pextractVoteOption,
|
||||||
|
|
@ -35,13 +37,8 @@ import Agora.Stake (
|
||||||
pisVoter,
|
pisVoter,
|
||||||
presolveStakeInputDatum,
|
presolveStakeInputDatum,
|
||||||
)
|
)
|
||||||
import Agora.Utils (
|
import Agora.Utils (ptaggedSymbolValueOf, ptoScottEncodingT)
|
||||||
pfromSingleton,
|
import Data.Function (on)
|
||||||
pinsertUniqueBy,
|
|
||||||
plistEqualsBy,
|
|
||||||
pmapMaybe,
|
|
||||||
ptryFromRedeemer,
|
|
||||||
)
|
|
||||||
import Plutarch.Api.V1 (PCredential, PCurrencySymbol)
|
import Plutarch.Api.V1 (PCredential, PCurrencySymbol)
|
||||||
import Plutarch.Api.V1.AssocMap (plookup)
|
import Plutarch.Api.V1.AssocMap (plookup)
|
||||||
import Plutarch.Api.V2 (
|
import Plutarch.Api.V2 (
|
||||||
|
|
@ -52,11 +49,15 @@ import Plutarch.Api.V2 (
|
||||||
)
|
)
|
||||||
import Plutarch.Extra.AssetClass (
|
import Plutarch.Extra.AssetClass (
|
||||||
PAssetClassData,
|
PAssetClassData,
|
||||||
ptoScottEncoding,
|
|
||||||
)
|
)
|
||||||
import Plutarch.Extra.Category (PCategory (pidentity))
|
import Plutarch.Extra.Category (PCategory (pidentity))
|
||||||
import Plutarch.Extra.Field (pletAll, pletAllC)
|
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" Plutarch.Extra.Map (pupdate)
|
||||||
import Plutarch.Extra.Maybe (
|
import Plutarch.Extra.Maybe (
|
||||||
passertPJust,
|
passertPJust,
|
||||||
|
|
@ -66,13 +67,15 @@ import Plutarch.Extra.Maybe (
|
||||||
pmaybe,
|
pmaybe,
|
||||||
pnothing,
|
pnothing,
|
||||||
)
|
)
|
||||||
import Plutarch.Extra.Ord (pfromOrdBy, psort)
|
import Plutarch.Extra.Ord (pfromOrdBy, pinsertUniqueBy, psort)
|
||||||
import Plutarch.Extra.Record (mkRecordConstr, (.&), (.=))
|
import Plutarch.Extra.Record (mkRecordConstr, (.&), (.=))
|
||||||
import Plutarch.Extra.ScriptContext (
|
import Plutarch.Extra.ScriptContext (
|
||||||
pfindTxInByTxOutRef,
|
pfindTxInByTxOutRef,
|
||||||
pfromOutputDatum,
|
ptryFromOutputDatum,
|
||||||
|
pvalidatorHashFromAddress,
|
||||||
)
|
)
|
||||||
import Plutarch.Extra.Sum (PSum (PSum))
|
import Plutarch.Extra.Sum (PSum (PSum))
|
||||||
|
import Plutarch.Extra.Tagged (PTagged)
|
||||||
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (
|
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (
|
||||||
pguardC,
|
pguardC,
|
||||||
pletC,
|
pletC,
|
||||||
|
|
@ -80,8 +83,9 @@ import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (
|
||||||
pmatchC,
|
pmatchC,
|
||||||
ptryFromC,
|
ptryFromC,
|
||||||
)
|
)
|
||||||
|
import Plutarch.Extra.Time (PCurrentTime)
|
||||||
import Plutarch.Extra.Traversable (pfoldMap)
|
import Plutarch.Extra.Traversable (pfoldMap)
|
||||||
import Plutarch.Extra.Value (passetClassValueOf, psymbolValueOf)
|
import Plutarch.Extra.Value (psymbolValueOf')
|
||||||
import Plutarch.Unsafe (punsafeCoerce)
|
import Plutarch.Unsafe (punsafeCoerce)
|
||||||
|
|
||||||
{- | Policy for Proposals.
|
{- | Policy for Proposals.
|
||||||
|
|
@ -109,7 +113,7 @@ import Plutarch.Unsafe (punsafeCoerce)
|
||||||
|
|
||||||
@since 1.0.0
|
@since 1.0.0
|
||||||
-}
|
-}
|
||||||
proposalPolicy :: ClosedTerm (PAssetClassData :--> PMintingPolicy)
|
proposalPolicy :: ClosedTerm (PTagged GovernorSTTag PAssetClassData :--> PMintingPolicy)
|
||||||
proposalPolicy =
|
proposalPolicy =
|
||||||
plam $ \gstAssetClass _redeemer ctx -> unTermCont $ do
|
plam $ \gstAssetClass _redeemer ctx -> unTermCont $ do
|
||||||
ctxF <- pletAllC ctx
|
ctxF <- pletAllC ctx
|
||||||
|
|
@ -117,44 +121,25 @@ proposalPolicy =
|
||||||
|
|
||||||
PMinting ((pfield @"_0" #) -> ownSymbol) <- pmatchC $ pfromData ctxF.purpose
|
PMinting ((pfield @"_0" #) -> ownSymbol) <- pmatchC $ pfromData ctxF.purpose
|
||||||
|
|
||||||
let mintedProposalST =
|
pguardC "Minted exactly one proposal ST"
|
||||||
psymbolValueOf
|
$ pmatch
|
||||||
|
( pfromJust
|
||||||
|
#$ psymbolValueOf'
|
||||||
# ownSymbol
|
# ownSymbol
|
||||||
# txInfoF.mint
|
# txInfoF.mint
|
||||||
|
)
|
||||||
|
$ \(PPair minted burnt) ->
|
||||||
|
minted
|
||||||
|
#== 1
|
||||||
|
#&& ptraceIfFalse "Burning a proposal is not supported" (burnt #== 0)
|
||||||
|
|
||||||
pguardC "Minted exactly one proposal ST" $
|
let governorRedeemer =
|
||||||
mintedProposalST #== 1
|
|
||||||
|
|
||||||
let governorInputRef =
|
|
||||||
passertPJust
|
passertPJust
|
||||||
# "GST should move"
|
# "GST should move"
|
||||||
#$ pfindJust
|
#$ presolveGovernorRedeemer
|
||||||
# plam
|
# (ptoScottEncodingT # gstAssetClass)
|
||||||
( flip pletAll $ \inputF ->
|
|
||||||
let value = pfield @"value" # inputF.resolved
|
|
||||||
isGovernorInput =
|
|
||||||
passetClassValueOf
|
|
||||||
# (ptoScottEncoding # gstAssetClass)
|
|
||||||
# value
|
|
||||||
#== 1
|
|
||||||
in pif
|
|
||||||
isGovernorInput
|
|
||||||
(pjust # inputF.outRef)
|
|
||||||
pnothing
|
|
||||||
)
|
|
||||||
# pfromData txInfoF.inputs
|
# pfromData txInfoF.inputs
|
||||||
|
# txInfoF.redeemers
|
||||||
governorScriptPurpose =
|
|
||||||
mkRecordConstr
|
|
||||||
PSpending
|
|
||||||
(#_0 .= governorInputRef)
|
|
||||||
|
|
||||||
governorRedeemer =
|
|
||||||
pfromData $
|
|
||||||
pfromJust
|
|
||||||
#$ ptryFromRedeemer @(PAsData PGovernorRedeemer)
|
|
||||||
# governorScriptPurpose
|
|
||||||
# txInfoF.redeemers
|
|
||||||
|
|
||||||
pguardC "Govenor redeemer correct" $
|
pguardC "Govenor redeemer correct" $
|
||||||
pcon PCreateProposal #== governorRedeemer
|
pcon PCreateProposal #== governorRedeemer
|
||||||
|
|
@ -239,9 +224,9 @@ instance DerivePlutusType PStakeInputsContext where
|
||||||
-}
|
-}
|
||||||
proposalValidator ::
|
proposalValidator ::
|
||||||
ClosedTerm
|
ClosedTerm
|
||||||
( PAssetClassData
|
( PTagged StakeSTTag PAssetClassData
|
||||||
:--> PCurrencySymbol
|
:--> PTagged GovernorSTTag PCurrencySymbol
|
||||||
:--> PCurrencySymbol
|
:--> PTagged ProposalSTTag PCurrencySymbol
|
||||||
:--> PInteger
|
:--> PInteger
|
||||||
:--> PValidator
|
:--> PValidator
|
||||||
)
|
)
|
||||||
|
|
@ -300,16 +285,18 @@ proposalValidator =
|
||||||
foldl1
|
foldl1
|
||||||
(#&&)
|
(#&&)
|
||||||
[ ptraceIfFalse "Own by proposal validator" $
|
[ ptraceIfFalse "Own by proposal validator" $
|
||||||
outputF.address #== proposalInputF.address
|
((#==) `on` (pvalidatorHashFromAddress #))
|
||||||
|
outputF.address
|
||||||
|
proposalInputF.address
|
||||||
, ptraceIfFalse "Has proposal ST" $
|
, ptraceIfFalse "Has proposal ST" $
|
||||||
psymbolValueOf # pstSymbol # outputF.value #== 1
|
ptaggedSymbolValueOf # pstSymbol # outputF.value #== 1
|
||||||
]
|
]
|
||||||
|
|
||||||
handleProposalUTxO =
|
handleProposalUTxO =
|
||||||
-- Using inline datum to avoid O(n^2) lookup.
|
-- Using inline datum to avoid O(n^2) lookup.
|
||||||
pfromData $
|
pfromData $
|
||||||
ptrace "Resolve proposal datum" $
|
ptrace "Resolve proposal datum" $
|
||||||
pfromOutputDatum @(PAsData PProposalDatum)
|
ptryFromOutputDatum @(PAsData PProposalDatum)
|
||||||
# outputF.datum
|
# outputF.datum
|
||||||
# txInfoF.datums
|
# txInfoF.datums
|
||||||
in pif
|
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' <-
|
getTimingRelation' <-
|
||||||
pletC $
|
pletC $
|
||||||
let currentTime =
|
withCurrentTime $
|
||||||
passertPJust
|
pgetRelation
|
||||||
# "Current time should be resolved"
|
# proposalInputDatumF.timingConfig
|
||||||
#$ currentProposalTime
|
# proposalInputDatumF.startingTime
|
||||||
# txInfoF.validRange
|
|
||||||
in pgetRelation
|
|
||||||
# proposalInputDatumF.timingConfig
|
|
||||||
# proposalInputDatumF.startingTime
|
|
||||||
# currentTime
|
|
||||||
|
|
||||||
let getTimingRelation = (getTimingRelation' #) . pcon
|
let getTimingRelation = (getTimingRelation' #) . pcon
|
||||||
|
|
||||||
|
|
@ -342,18 +335,23 @@ proposalValidator =
|
||||||
resolveStakeInputDatum <-
|
resolveStakeInputDatum <-
|
||||||
pletC $
|
pletC $
|
||||||
presolveStakeInputDatum
|
presolveStakeInputDatum
|
||||||
# (ptoScottEncoding # sstClass)
|
# (ptoScottEncodingT # sstClass)
|
||||||
# txInfoF.datums
|
# txInfoF.datums
|
||||||
|
|
||||||
spendStakes' :: Term _ ((PStakeInputsContext :--> PUnit) :--> PUnit) <-
|
spendStakes' :: Term _ ((PStakeInputsContext :--> PUnit) :--> PUnit) <-
|
||||||
pletC $
|
pletC $
|
||||||
plam $
|
plam $ \val -> unTermCont $ do
|
||||||
let stakeInputs =
|
stakeInputs <-
|
||||||
pmapMaybe
|
pletC $
|
||||||
# resolveStakeInputDatum
|
pmapMaybe @PList
|
||||||
# pfromData txInfoF.inputs
|
# resolveStakeInputDatum
|
||||||
|
# pfromData txInfoF.inputs
|
||||||
|
|
||||||
ctx = pcon $ PStakeInputsContext stakeInputs
|
pguardC "Stake inputs not null" $
|
||||||
in (# ctx)
|
pnot #$ pnull # stakeInputs
|
||||||
|
|
||||||
|
let ctx = pcon $ PStakeInputsContext stakeInputs
|
||||||
|
pure $ val # ctx
|
||||||
|
|
||||||
let spendStakes ::
|
let spendStakes ::
|
||||||
( PStakeInputsContext _ ->
|
( PStakeInputsContext _ ->
|
||||||
|
|
@ -439,7 +437,7 @@ proposalValidator =
|
||||||
stakeF <-
|
stakeF <-
|
||||||
pletFieldsC @'["owner", "stakedAmount"] $
|
pletFieldsC @'["owner", "stakedAmount"] $
|
||||||
ptrace "Exactly one stake input" $
|
ptrace "Exactly one stake input" $
|
||||||
pfromSingleton # sctxF.inputStakes
|
ptryFromSingleton # sctxF.inputStakes
|
||||||
|
|
||||||
let newCosigner = stakeF.owner
|
let newCosigner = stakeF.owner
|
||||||
|
|
||||||
|
|
@ -512,6 +510,12 @@ proposalValidator =
|
||||||
pguardC "Proposal time should be wthin the voting period" $
|
pguardC "Proposal time should be wthin the voting period" $
|
||||||
pisWithin # getTimingRelation PVotingPeriod
|
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).
|
-- Ensure the transaction is voting to a valid 'ResultTag'(outcome).
|
||||||
PProposalVotes voteMap <- pmatchC proposalInputDatumF.votes
|
PProposalVotes voteMap <- pmatchC proposalInputDatumF.votes
|
||||||
voteFor <- pletC $ pfromData $ pfield @"resultTag" # r
|
voteFor <- pletC $ pfromData $ pfield @"resultTag" # r
|
||||||
|
|
@ -563,40 +567,41 @@ proposalValidator =
|
||||||
|
|
||||||
PUnlockStake _ -> spendStakes $ \sctxF -> do
|
PUnlockStake _ -> spendStakes $ \sctxF -> do
|
||||||
let expectedVotes =
|
let expectedVotes =
|
||||||
pfoldl
|
pdata $
|
||||||
# plam
|
pfoldl
|
||||||
( \votes stake -> unTermCont $ do
|
# plam
|
||||||
stakeF <-
|
( \votes stake -> unTermCont $ do
|
||||||
pletFieldsC
|
stakeF <-
|
||||||
@'["stakedAmount", "lockedBy"]
|
pletFieldsC
|
||||||
stake
|
@'["stakedAmount", "lockedBy"]
|
||||||
|
stake
|
||||||
|
|
||||||
stakeRoles <-
|
stakeRoles <-
|
||||||
pletC $
|
pletC $
|
||||||
pgetStakeRoles
|
pgetStakeRoles
|
||||||
# proposalInputDatumF.proposalId
|
# proposalInputDatumF.proposalId
|
||||||
# stakeF.lockedBy
|
# stakeF.lockedBy
|
||||||
|
|
||||||
pguardC "Stake input should be relevant" $
|
pguardC "Stake input should be relevant" $
|
||||||
pnot #$ pisIrrelevant # stakeRoles
|
pnot #$ pisIrrelevant # stakeRoles
|
||||||
|
|
||||||
let canRetractVotes =
|
let canRetractVotes =
|
||||||
pisVoter # stakeRoles
|
pisVoter # stakeRoles
|
||||||
|
|
||||||
voteCount =
|
voteCount =
|
||||||
pto $
|
pto $
|
||||||
pfromData stakeF.stakedAmount
|
pfromData stakeF.stakedAmount
|
||||||
|
|
||||||
newVotes =
|
newVotes =
|
||||||
pretractVotes
|
pretractVotes
|
||||||
# (pextractVoteOption # stakeRoles)
|
# (pextractVoteOption # stakeRoles)
|
||||||
# voteCount
|
# voteCount
|
||||||
# votes
|
# votes
|
||||||
|
|
||||||
pure $ pif canRetractVotes newVotes votes
|
pure $ pif canRetractVotes newVotes votes
|
||||||
)
|
)
|
||||||
# proposalInputDatumF.votes
|
# proposalInputDatumF.votes
|
||||||
# sctxF.inputStakes
|
# sctxF.inputStakes
|
||||||
|
|
||||||
inVotingPeriod =
|
inVotingPeriod =
|
||||||
pisWithin # getTimingRelation PVotingPeriod
|
pisWithin # getTimingRelation PVotingPeriod
|
||||||
|
|
@ -625,14 +630,19 @@ proposalValidator =
|
||||||
.& #thresholds
|
.& #thresholds
|
||||||
.= proposalInputDatumF.thresholds
|
.= proposalInputDatumF.thresholds
|
||||||
.& #votes
|
.& #votes
|
||||||
.= pdata expectedVotes
|
.= expectedVotes
|
||||||
.& #timingConfig
|
.& #timingConfig
|
||||||
.= proposalInputDatumF.timingConfig
|
.= proposalInputDatumF.timingConfig
|
||||||
.& #startingTime
|
.& #startingTime
|
||||||
.= proposalInputDatumF.startingTime
|
.= proposalInputDatumF.startingTime
|
||||||
)
|
)
|
||||||
in ptraceIfFalse "Update votes" $
|
in foldl1
|
||||||
expectedProposalOut #== proposalOutputDatum
|
(#&&)
|
||||||
|
[ ptraceIfFalse "Votes changed" $
|
||||||
|
pnot #$ expectedVotes #== proposalInputDatumF.votes
|
||||||
|
, ptraceIfFalse "Proposal update correct" $
|
||||||
|
expectedProposalOut #== proposalOutputDatum
|
||||||
|
]
|
||||||
)
|
)
|
||||||
-- No change to the proposal is allowed.
|
-- No change to the proposal is allowed.
|
||||||
( ptraceIfFalse "Proposal unchanged" $
|
( ptraceIfFalse "Proposal unchanged" $
|
||||||
|
|
@ -728,7 +738,7 @@ proposalValidator =
|
||||||
. (pfield @"resolved" #) ->
|
. (pfield @"resolved" #) ->
|
||||||
value
|
value
|
||||||
) ->
|
) ->
|
||||||
psymbolValueOf # gstSymbol # value #== 1
|
ptaggedSymbolValueOf # gstSymbol # value #== 1
|
||||||
)
|
)
|
||||||
# pfromData txInfoF.inputs
|
# pfromData txInfoF.inputs
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,16 +22,15 @@ module Agora.Proposal.Time (
|
||||||
PPeriod (..),
|
PPeriod (..),
|
||||||
|
|
||||||
-- * Compute periods given config and starting time.
|
-- * Compute periods given config and starting time.
|
||||||
validateProposalStartingTime,
|
pvalidateProposalStartingTime,
|
||||||
currentProposalTime,
|
pcurrentProposalTime,
|
||||||
pisProposalTimingConfigValid,
|
pisProposalTimingConfigValid,
|
||||||
pisMaxTimeRangeWidthValid,
|
pisMaxTimeRangeWidthValid,
|
||||||
pgetRelation,
|
pgetRelation,
|
||||||
pisWithin,
|
pisWithin,
|
||||||
|
psatisfyMaximumWidth,
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Agora.Utils (pcurrentTimeDuration)
|
|
||||||
import Control.Composition ((.*))
|
|
||||||
import Data.Functor ((<&>))
|
import Data.Functor ((<&>))
|
||||||
import Plutarch.Api.V1 (
|
import Plutarch.Api.V1 (
|
||||||
PExtended (PFinite),
|
PExtended (PFinite),
|
||||||
|
|
@ -46,12 +45,14 @@ import Plutarch.DataRepr (
|
||||||
PDataFields,
|
PDataFields,
|
||||||
)
|
)
|
||||||
import Plutarch.Extra.Applicative (PApply (pliftA2))
|
import Plutarch.Extra.Applicative (PApply (pliftA2))
|
||||||
|
import Plutarch.Extra.Bool (passert)
|
||||||
import Plutarch.Extra.Field (pletAll, pletAllC)
|
import Plutarch.Extra.Field (pletAll, pletAllC)
|
||||||
import Plutarch.Extra.IsData (PlutusTypeEnumData)
|
import Plutarch.Extra.IsData (PlutusTypeEnumData)
|
||||||
import Plutarch.Extra.Maybe (pjust, pmaybe, pnothing)
|
import Plutarch.Extra.Maybe (pjust, pmaybe, pnothing)
|
||||||
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pletC, pmatchC)
|
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pletC, pmatchC)
|
||||||
import Plutarch.Extra.Time (
|
import Plutarch.Extra.Time (
|
||||||
PCurrentTime (PCurrentTime),
|
PCurrentTime (PCurrentTime),
|
||||||
|
pcurrentTimeDuration,
|
||||||
pisWithinCurrentTime,
|
pisWithinCurrentTime,
|
||||||
)
|
)
|
||||||
import Plutarch.Lift (
|
import Plutarch.Lift (
|
||||||
|
|
@ -59,6 +60,7 @@ import Plutarch.Lift (
|
||||||
PConstantDecl,
|
PConstantDecl,
|
||||||
PUnsafeLiftDecl (PLifted),
|
PUnsafeLiftDecl (PLifted),
|
||||||
)
|
)
|
||||||
|
import Plutarch.Num (PNum)
|
||||||
import PlutusLedgerApi.V1 (POSIXTime)
|
import PlutusLedgerApi.V1 (POSIXTime)
|
||||||
import PlutusTx qualified
|
import PlutusTx qualified
|
||||||
|
|
||||||
|
|
@ -88,33 +90,6 @@ newtype ProposalStartingTime = ProposalStartingTime
|
||||||
PlutusTx.UnsafeFromData
|
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'.
|
-- | Represents the maximum width of a 'PlutusLedgerApi.V1.Time.POSIXTimeRange'.
|
||||||
newtype MaxTimeRangeWidth = MaxTimeRangeWidth {getMaxWidth :: POSIXTime}
|
newtype MaxTimeRangeWidth = MaxTimeRangeWidth {getMaxWidth :: POSIXTime}
|
||||||
deriving stock
|
deriving stock
|
||||||
|
|
@ -134,8 +109,41 @@ newtype MaxTimeRangeWidth = MaxTimeRangeWidth {getMaxWidth :: POSIXTime}
|
||||||
PlutusTx.FromData
|
PlutusTx.FromData
|
||||||
, -- | @since 0.1.0
|
, -- | @since 0.1.0
|
||||||
PlutusTx.UnsafeFromData
|
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.
|
{- | == Establishing timing in Proposal interactions.
|
||||||
|
|
@ -210,6 +218,8 @@ newtype PProposalTimingConfig (s :: S) = PProposalTimingConfig
|
||||||
, "votingTime" ':= PPOSIXTime
|
, "votingTime" ':= PPOSIXTime
|
||||||
, "lockingTime" ':= PPOSIXTime
|
, "lockingTime" ':= PPOSIXTime
|
||||||
, "executingTime" ':= PPOSIXTime
|
, "executingTime" ':= PPOSIXTime
|
||||||
|
, "minStakeVotingTime" ':= PPOSIXTime
|
||||||
|
, "votingTimeRangeMaxWidth" ':= PMaxTimeRangeWidth
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -224,6 +234,8 @@ newtype PProposalTimingConfig (s :: S) = PProposalTimingConfig
|
||||||
PIsData
|
PIsData
|
||||||
, -- | @since 0.1.0
|
, -- | @since 0.1.0
|
||||||
PDataFields
|
PDataFields
|
||||||
|
, -- | @since 0.2.1
|
||||||
|
PShow
|
||||||
)
|
)
|
||||||
|
|
||||||
instance DerivePlutusType PProposalTimingConfig where
|
instance DerivePlutusType PProposalTimingConfig where
|
||||||
|
|
@ -260,6 +272,10 @@ newtype PMaxTimeRangeWidth (s :: S)
|
||||||
PPartialOrd
|
PPartialOrd
|
||||||
, -- | @since 0.1.0
|
, -- | @since 0.1.0
|
||||||
POrd
|
POrd
|
||||||
|
, -- | @since 0.2.1
|
||||||
|
PShow
|
||||||
|
, -- | @since 1.0.0
|
||||||
|
PNum
|
||||||
)
|
)
|
||||||
|
|
||||||
instance DerivePlutusType PMaxTimeRangeWidth where
|
instance DerivePlutusType PMaxTimeRangeWidth where
|
||||||
|
|
@ -303,6 +319,8 @@ pisProposalTimingConfigValid = phoistAcyclic $
|
||||||
, confF.votingTime
|
, confF.votingTime
|
||||||
, confF.lockingTime
|
, confF.lockingTime
|
||||||
, confF.executingTime
|
, confF.executingTime
|
||||||
|
, confF.minStakeVotingTime
|
||||||
|
, pto confF.votingTimeRangeMaxWidth
|
||||||
]
|
]
|
||||||
|
|
||||||
{- | Return true if the maximum time width is greater than 0.
|
{- | Return true if the maximum time width is greater than 0.
|
||||||
|
|
@ -322,7 +340,7 @@ pisMaxTimeRangeWidthValid =
|
||||||
|
|
||||||
@since 1.0.0
|
@since 1.0.0
|
||||||
-}
|
-}
|
||||||
validateProposalStartingTime ::
|
pvalidateProposalStartingTime ::
|
||||||
forall (s :: S).
|
forall (s :: S).
|
||||||
Term
|
Term
|
||||||
s
|
s
|
||||||
|
|
@ -331,26 +349,23 @@ validateProposalStartingTime ::
|
||||||
:--> PProposalStartingTime
|
:--> PProposalStartingTime
|
||||||
:--> PBool
|
:--> PBool
|
||||||
)
|
)
|
||||||
validateProposalStartingTime = phoistAcyclic $
|
pvalidateProposalStartingTime = phoistAcyclic $
|
||||||
plam $ \(pto -> maxDuration) iv (pto -> st) ->
|
plam $ \maxWidth iv (pto -> st) ->
|
||||||
pmaybe
|
pmaybe
|
||||||
# ptrace
|
# pconstant False
|
||||||
"validateProposalStartingTime: unable to get current time"
|
|
||||||
(pconstant False)
|
|
||||||
# plam
|
# plam
|
||||||
( \ct ->
|
( \ct ->
|
||||||
let duration = pcurrentTimeDuration # ct
|
let isTightEnough =
|
||||||
isTightEnough =
|
|
||||||
ptraceIfFalse
|
ptraceIfFalse
|
||||||
"createProposalStartingTime: given time range should be tight enough"
|
"createProposalStartingTime: given time range should be tight enough"
|
||||||
$ duration #<= maxDuration
|
$ psatisfyMaximumWidth # maxWidth # ct
|
||||||
isInCurrentTimeRange =
|
isInCurrentTimeRange =
|
||||||
ptraceIfFalse
|
ptraceIfFalse
|
||||||
"createProposalStartingTime: starting time should be in current time range"
|
"createProposalStartingTime: starting time should be in current time range"
|
||||||
$ pisWithinCurrentTime # st # ct
|
$ pisWithinCurrentTime # st # ct
|
||||||
in isTightEnough #&& isInCurrentTimeRange
|
in isTightEnough #&& isInCurrentTimeRange
|
||||||
)
|
)
|
||||||
# (currentProposalTime # iv)
|
# (pcurrentProposalTime # iv)
|
||||||
|
|
||||||
{- | Get the current proposal time, given the 'PlutusLedgerApi.V1.txInfoValidPeriod' field.
|
{- | Get the current proposal time, given the 'PlutusLedgerApi.V1.txInfoValidPeriod' field.
|
||||||
|
|
||||||
|
|
@ -364,8 +379,8 @@ validateProposalStartingTime = phoistAcyclic $
|
||||||
|
|
||||||
@since 0.1.0
|
@since 0.1.0
|
||||||
-}
|
-}
|
||||||
currentProposalTime :: forall (s :: S). Term s (PPOSIXTimeRange :--> PMaybe PProposalTime)
|
pcurrentProposalTime :: forall (s :: S). Term s (PPOSIXTimeRange :--> PMaybe PProposalTime)
|
||||||
currentProposalTime = phoistAcyclic $
|
pcurrentProposalTime = phoistAcyclic $
|
||||||
plam $ \iv -> unTermCont $ do
|
plam $ \iv -> unTermCont $ do
|
||||||
PInterval iv' <- pmatchC iv
|
PInterval iv' <- pmatchC iv
|
||||||
ivf <- pletAllC iv'
|
ivf <- pletAllC iv'
|
||||||
|
|
@ -386,7 +401,13 @@ currentProposalTime = phoistAcyclic $
|
||||||
PFinite (pfromData . (pfield @"_0" #) -> d) -> pjust # d
|
PFinite (pfromData . (pfield @"_0" #) -> d) -> pjust # d
|
||||||
_ -> ptrace "currentProposalTime: time range should be bounded" pnothing
|
_ -> 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
|
pure $ pliftA2 # mkTime # lowerBound # upperBound
|
||||||
|
|
||||||
{- | Represent relation between current time and a given period.
|
{- | Represent relation between current time and a given period.
|
||||||
|
|
@ -494,3 +515,22 @@ pgetRelation = phoistAcyclic $
|
||||||
pif (plb #<= lb #&& ub #<= pub) (pcon PWithin) $
|
pif (plb #<= lb #&& ub #<= pub) (pcon PWithin) $
|
||||||
pif (pub #< lb) (pcon PAfter) $
|
pif (pub #< lb) (pcon PAfter) $
|
||||||
ptraceError "pgetRelation: too early or invalid current time"
|
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
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,13 @@ module Agora.Stake (
|
||||||
-- * Haskell-land
|
-- * Haskell-land
|
||||||
StakeDatum (..),
|
StakeDatum (..),
|
||||||
StakeRedeemer (..),
|
StakeRedeemer (..),
|
||||||
|
ProposalAction (..),
|
||||||
ProposalLock (..),
|
ProposalLock (..),
|
||||||
|
|
||||||
-- * Plutarch-land
|
-- * Plutarch-land
|
||||||
PStakeDatum (..),
|
PStakeDatum (..),
|
||||||
PStakeRedeemer (..),
|
PStakeRedeemer (..),
|
||||||
|
PProposalAction (..),
|
||||||
PProposalLock (..),
|
PProposalLock (..),
|
||||||
PStakeRole (..),
|
PStakeRole (..),
|
||||||
|
|
||||||
|
|
@ -42,18 +44,18 @@ module Agora.Stake (
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Agora.Proposal (
|
import Agora.Proposal (
|
||||||
|
PProposalDatum,
|
||||||
PProposalId,
|
PProposalId,
|
||||||
PProposalRedeemer,
|
PProposalRedeemer,
|
||||||
PProposalStatus,
|
|
||||||
PResultTag,
|
PResultTag,
|
||||||
ProposalId,
|
ProposalId,
|
||||||
ResultTag,
|
ResultTag,
|
||||||
)
|
)
|
||||||
import Agora.SafeMoney (GTTag)
|
import Agora.Proposal.Time (PProposalTime)
|
||||||
import Agora.Utils (pmapMaybe, ppureIf)
|
import Agora.SafeMoney (GTTag, StakeSTTag)
|
||||||
import Data.Tagged (Tagged)
|
import Data.Tagged (Tagged)
|
||||||
import Generics.SOP qualified as SOP
|
import Generics.SOP qualified as SOP
|
||||||
import Plutarch.Api.V1 (PCredential)
|
import Plutarch.Api.V1 (PCredential, PPOSIXTime)
|
||||||
import Plutarch.Api.V2 (
|
import Plutarch.Api.V2 (
|
||||||
KeyGuarantees (Unsorted),
|
KeyGuarantees (Unsorted),
|
||||||
PDatum,
|
PDatum,
|
||||||
|
|
@ -67,26 +69,62 @@ import Plutarch.DataRepr (
|
||||||
DerivePConstantViaData (DerivePConstantViaData),
|
DerivePConstantViaData (DerivePConstantViaData),
|
||||||
PDataFields,
|
PDataFields,
|
||||||
)
|
)
|
||||||
|
import Plutarch.Extra.Applicative (ppureIf)
|
||||||
import Plutarch.Extra.AssetClass (PAssetClass)
|
import Plutarch.Extra.AssetClass (PAssetClass)
|
||||||
import Plutarch.Extra.Field (pletAll)
|
|
||||||
import Plutarch.Extra.IsData (
|
import Plutarch.Extra.IsData (
|
||||||
DerivePConstantViaDataList (DerivePConstantViaDataList),
|
DerivePConstantViaDataList (DerivePConstantViaDataList),
|
||||||
ProductIsData (ProductIsData),
|
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.Maybe (passertPJust, pjust, pnothing)
|
||||||
import Plutarch.Extra.ScriptContext (pfromOutputDatum)
|
import Plutarch.Extra.ScriptContext (ptryFromOutputDatum)
|
||||||
import Plutarch.Extra.Sum (PSum (PSum))
|
import Plutarch.Extra.Sum (PSum (PSum))
|
||||||
import Plutarch.Extra.Tagged (PTagged)
|
import Plutarch.Extra.Tagged (PTagged)
|
||||||
import Plutarch.Extra.Traversable (pfoldMap)
|
import Plutarch.Extra.Traversable (pfoldMap)
|
||||||
import Plutarch.Extra.Value (passetClassValueOf)
|
import Plutarch.Extra.Value (passetClassValueOfT)
|
||||||
import Plutarch.Lift (PConstantDecl, PUnsafeLiftDecl (PLifted))
|
import Plutarch.Lift (PConstantDecl, PUnsafeLiftDecl (PLifted))
|
||||||
import Plutarch.Orphans ()
|
import PlutusLedgerApi.V2 (Credential, POSIXTime)
|
||||||
import PlutusLedgerApi.V2 (Credential)
|
|
||||||
import PlutusTx qualified
|
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.
|
{- | Locks that are stored in the stake datums for various purposes.
|
||||||
|
|
||||||
NOTE: Due to retracting votes always being possible,
|
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
|
data ProposalLock = ProposalLock
|
||||||
= -- | The stake was used to create a proposal.
|
{ proposalId :: ProposalId
|
||||||
--
|
-- ^ The identifier of the proposal.
|
||||||
-- This kind of lock is placed upon the creation of a proposal, in order
|
, action :: ProposalAction
|
||||||
-- to limit creation of proposals per stake.
|
-- ^ The action that has been performed.
|
||||||
--
|
}
|
||||||
-- 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
|
|
||||||
deriving stock
|
deriving stock
|
||||||
( -- | @since 0.1.0
|
( -- | @since 0.1.0
|
||||||
Show
|
Show
|
||||||
, -- | @since 0.1.0
|
, -- | @since 0.1.0
|
||||||
Generic
|
Generic
|
||||||
)
|
)
|
||||||
|
deriving anyclass
|
||||||
PlutusTx.makeIsDataIndexed
|
( -- | @since 0.1.0
|
||||||
''ProposalLock
|
SOP.Generic
|
||||||
[ ('Created, 0)
|
)
|
||||||
, ('Voted, 1)
|
deriving
|
||||||
, ('Cosigned, 2)
|
( -- | @since 0.1.0
|
||||||
]
|
PlutusTx.ToData
|
||||||
|
, -- | @since 0.1.0
|
||||||
|
PlutusTx.FromData
|
||||||
|
)
|
||||||
|
via (ProductIsData ProposalLock)
|
||||||
|
|
||||||
{- | Haskell-level redeemer for Stake scripts.
|
{- | Haskell-level redeemer for Stake scripts.
|
||||||
|
|
||||||
|
|
@ -160,7 +184,7 @@ data StakeRedeemer
|
||||||
= -- | Deposit or withdraw a discrete amount of the staked governance token.
|
= -- | Deposit or withdraw a discrete amount of the staked governance token.
|
||||||
-- Stake must be unlocked.
|
-- Stake must be unlocked.
|
||||||
DepositWithdraw (Tagged GTTag Integer)
|
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.
|
-- Stake must be unlocked.
|
||||||
Destroy
|
Destroy
|
||||||
| -- | Permit a Vote to be added onto a 'Agora.Proposal.Proposal'.
|
| -- | Permit a Vote to be added onto a 'Agora.Proposal.Proposal'.
|
||||||
|
|
@ -268,6 +292,7 @@ newtype PStakeDatum (s :: S) = PStakeDatum
|
||||||
PShow
|
PShow
|
||||||
)
|
)
|
||||||
|
|
||||||
|
-- | @since 1.0.0
|
||||||
instance DerivePlutusType PStakeDatum where
|
instance DerivePlutusType PStakeDatum where
|
||||||
type DPTStrat _ = PlutusTypeNewtype
|
type DPTStrat _ = PlutusTypeNewtype
|
||||||
|
|
||||||
|
|
@ -291,7 +316,7 @@ instance PTryFrom PData (PAsData PStakeDatum)
|
||||||
data PStakeRedeemer (s :: S)
|
data PStakeRedeemer (s :: S)
|
||||||
= -- | Deposit or withdraw a discrete amount of the staked governance token.
|
= -- | Deposit or withdraw a discrete amount of the staked governance token.
|
||||||
PDepositWithdraw (Term s (PDataRecord '["delta" ':= PTagged GTTag PInteger]))
|
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 '[]))
|
PDestroy (Term s (PDataRecord '[]))
|
||||||
| PPermitVote (Term s (PDataRecord '[]))
|
| PPermitVote (Term s (PDataRecord '[]))
|
||||||
| PRetractVotes (Term s (PDataRecord '[]))
|
| PRetractVotes (Term s (PDataRecord '[]))
|
||||||
|
|
@ -325,32 +350,65 @@ deriving via
|
||||||
instance
|
instance
|
||||||
(PConstantDecl StakeRedeemer)
|
(PConstantDecl StakeRedeemer)
|
||||||
|
|
||||||
{- | Plutarch-level version of 'ProposalLock'.
|
{- | Plutarch-level version of 'ProposalAction'.
|
||||||
|
|
||||||
@since 0.2.0
|
@since 1.0.0
|
||||||
-}
|
-}
|
||||||
data PProposalLock (s :: S)
|
data PProposalAction (s :: S)
|
||||||
= PCreated
|
= PCreated (Term s (PDataRecord '[]))
|
||||||
( Term
|
|
||||||
s
|
|
||||||
( PDataRecord
|
|
||||||
'["created" ':= PProposalId]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
| PVoted
|
| PVoted
|
||||||
( Term
|
( Term
|
||||||
s
|
s
|
||||||
( PDataRecord
|
( 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
|
( Term
|
||||||
s
|
s
|
||||||
( PDataRecord
|
( PDataRecord
|
||||||
'[ "cosigned" ':= PProposalId
|
'[ "proposalId" ':= PProposalId
|
||||||
|
, "action" ':= PProposalAction
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
@ -365,15 +423,15 @@ data PProposalLock (s :: S)
|
||||||
PIsData
|
PIsData
|
||||||
, -- | @since 0.1.0
|
, -- | @since 0.1.0
|
||||||
PEq
|
PEq
|
||||||
|
, -- | @since 1.0.0
|
||||||
|
PDataFields
|
||||||
, -- | @since 0.2.0
|
, -- | @since 0.2.0
|
||||||
PShow
|
PShow
|
||||||
)
|
)
|
||||||
|
|
||||||
|
-- | @since 0.2.0
|
||||||
instance DerivePlutusType PProposalLock where
|
instance DerivePlutusType PProposalLock where
|
||||||
type DPTStrat _ = PlutusTypeData
|
type DPTStrat _ = PlutusTypeNewtype
|
||||||
|
|
||||||
-- | @since 0.1.0
|
|
||||||
instance PTryFrom PData PProposalLock
|
|
||||||
|
|
||||||
-- | @since 0.2.0
|
-- | @since 0.2.0
|
||||||
instance PTryFrom PData (PAsData PProposalLock)
|
instance PTryFrom PData (PAsData PProposalLock)
|
||||||
|
|
@ -384,7 +442,7 @@ instance PUnsafeLiftDecl PProposalLock where
|
||||||
|
|
||||||
-- | @since 0.1.0
|
-- | @since 0.1.0
|
||||||
deriving via
|
deriving via
|
||||||
(DerivePConstantViaData ProposalLock PProposalLock)
|
(DerivePConstantViaDataList ProposalLock PProposalLock)
|
||||||
instance
|
instance
|
||||||
(PConstantDecl ProposalLock)
|
(PConstantDecl ProposalLock)
|
||||||
|
|
||||||
|
|
@ -412,9 +470,11 @@ pnumCreatedProposals =
|
||||||
pto $
|
pto $
|
||||||
pfoldMap
|
pfoldMap
|
||||||
# plam
|
# plam
|
||||||
( \(pfromData -> lock) -> pmatch lock $ \case
|
( \lock ->
|
||||||
PCreated _ -> pcon $ PSum 1
|
let action = pfromData $ pfield @"action" # lock
|
||||||
_ -> mempty
|
in pmatch action $ \case
|
||||||
|
PCreated _ -> pcon $ PSum 1
|
||||||
|
_ -> mempty
|
||||||
)
|
)
|
||||||
# l
|
# l
|
||||||
|
|
||||||
|
|
@ -525,9 +585,9 @@ instance DerivePlutusType PStakeRedeemerContext where
|
||||||
data PProposalContext (s :: S)
|
data PProposalContext (s :: S)
|
||||||
= -- | A proposal is spent.
|
= -- | A proposal is spent.
|
||||||
PSpendProposal
|
PSpendProposal
|
||||||
(Term s PProposalId)
|
(Term s PProposalDatum)
|
||||||
(Term s PProposalStatus)
|
|
||||||
(Term s PProposalRedeemer)
|
(Term s PProposalRedeemer)
|
||||||
|
(Term s PProposalTime)
|
||||||
| -- | A new proposal is created.
|
| -- | A new proposal is created.
|
||||||
PNewProposal
|
PNewProposal
|
||||||
(Term s PProposalId)
|
(Term s PProposalId)
|
||||||
|
|
@ -665,26 +725,17 @@ pgetStakeRoles ::
|
||||||
)
|
)
|
||||||
pgetStakeRoles = phoistAcyclic $
|
pgetStakeRoles = phoistAcyclic $
|
||||||
plam $ \pid ->
|
plam $ \pid ->
|
||||||
pmapMaybe
|
let getStakeRole = flip (pletFields @'["proposalId", "action"]) $
|
||||||
# plam
|
\lockF ->
|
||||||
( flip
|
ppureIf
|
||||||
pmatch
|
# (pid #== lockF.proposalId)
|
||||||
( \case
|
#$ pmatch lockF.action
|
||||||
PCreated ((pfield @"created" #) -> pid') ->
|
$ \case
|
||||||
ppureIf
|
PCreated _ -> pcon PCreator
|
||||||
# (pid' #== pid)
|
PVoted ((pfield @"votedFor" #) -> tag) ->
|
||||||
# pcon PCreator
|
pcon $ PVoter tag
|
||||||
PVoted r -> pletAll r $ \rF ->
|
PCosigned _ -> pcon PCosigner
|
||||||
ppureIf
|
in pmapMaybe # plam (getStakeRole . pfromData)
|
||||||
# (rF.votedOn #== pid)
|
|
||||||
# pcon (PVoter rF.votedFor)
|
|
||||||
PCosigned ((pfield @"cosigned" #) -> pid') ->
|
|
||||||
ppureIf
|
|
||||||
# (pid' #== pid)
|
|
||||||
# pcon PCosigner
|
|
||||||
)
|
|
||||||
. pfromData
|
|
||||||
)
|
|
||||||
|
|
||||||
{- | Get the outcome that was voted for.
|
{- | Get the outcome that was voted for.
|
||||||
|
|
||||||
|
|
@ -715,7 +766,7 @@ presolveStakeInputDatum ::
|
||||||
forall (s :: S).
|
forall (s :: S).
|
||||||
Term
|
Term
|
||||||
s
|
s
|
||||||
( PAssetClass
|
( PTagged StakeSTTag PAssetClass
|
||||||
:--> PMap 'Unsorted PDatumHash PDatum
|
:--> PMap 'Unsorted PDatumHash PDatum
|
||||||
:--> PTxInInfo
|
:--> PTxInInfo
|
||||||
:--> PMaybe PStakeDatum
|
:--> PMaybe PStakeDatum
|
||||||
|
|
@ -726,7 +777,7 @@ presolveStakeInputDatum = phoistAcyclic $
|
||||||
(pletFields @'["value", "datum", "address"])
|
(pletFields @'["value", "datum", "address"])
|
||||||
( \txOutF ->
|
( \txOutF ->
|
||||||
let isStakeUTxO =
|
let isStakeUTxO =
|
||||||
passetClassValueOf
|
passetClassValueOfT
|
||||||
# sstClass
|
# sstClass
|
||||||
# txOutF.value
|
# txOutF.value
|
||||||
#== 1
|
#== 1
|
||||||
|
|
@ -734,7 +785,7 @@ presolveStakeInputDatum = phoistAcyclic $
|
||||||
datum =
|
datum =
|
||||||
ptrace "Resolve stake datum" $
|
ptrace "Resolve stake datum" $
|
||||||
pfromData $
|
pfromData $
|
||||||
pfromOutputDatum @(PAsData PStakeDatum)
|
ptryFromOutputDatum @(PAsData PStakeDatum)
|
||||||
# txOutF.datum
|
# txOutF.datum
|
||||||
# datums
|
# datums
|
||||||
in pif
|
in pif
|
||||||
|
|
|
||||||
|
|
@ -19,13 +19,15 @@ import Agora.Proposal (
|
||||||
PProposalRedeemer (PCosign, PUnlockStake, PVote),
|
PProposalRedeemer (PCosign, PUnlockStake, PVote),
|
||||||
ProposalStatus (Finished),
|
ProposalStatus (Finished),
|
||||||
)
|
)
|
||||||
|
import Agora.Proposal.Time (PProposalTime)
|
||||||
import Agora.Stake (
|
import Agora.Stake (
|
||||||
|
PProposalAction (PCosigned, PCreated, PVoted),
|
||||||
PProposalContext (
|
PProposalContext (
|
||||||
PNewProposal,
|
PNewProposal,
|
||||||
PNoProposal,
|
PNoProposal,
|
||||||
PSpendProposal
|
PSpendProposal
|
||||||
),
|
),
|
||||||
PProposalLock (PCosigned, PCreated, PVoted),
|
PProposalLock (PProposalLock),
|
||||||
PSigContext (owner, signedBy),
|
PSigContext (owner, signedBy),
|
||||||
PSignedBy (
|
PSignedBy (
|
||||||
PSignedByDelegate,
|
PSignedByDelegate,
|
||||||
|
|
@ -48,13 +50,20 @@ import Agora.Stake (
|
||||||
),
|
),
|
||||||
pstakeLocked,
|
pstakeLocked,
|
||||||
)
|
)
|
||||||
import Agora.Utils (pfromSingleton, pisSingleton, pmustDeleteBy)
|
import Data.Functor ((<&>))
|
||||||
import Plutarch.Api.V1.Address (PCredential)
|
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.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 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.
|
-- | A wrapper which ensures that no proposal is presented in the transaction.
|
||||||
pwithoutProposal ::
|
pwithoutProposal ::
|
||||||
|
|
@ -87,7 +96,7 @@ pbatchUpdateInputs = phoistAcyclic $
|
||||||
plam $ \f -> flip pmatch $ \ctxF ->
|
plam $ \f -> flip pmatch $ \ctxF ->
|
||||||
pnull
|
pnull
|
||||||
#$ pfoldr
|
#$ pfoldr
|
||||||
# (pmustDeleteBy # f)
|
# plam (\x -> ptryDeleteFirstBy # (f # x))
|
||||||
# ctxF.stakeOutputDatums
|
# ctxF.stakeOutputDatums
|
||||||
# ctxF.stakeInputDatums
|
# ctxF.stakeInputDatums
|
||||||
|
|
||||||
|
|
@ -159,17 +168,13 @@ pvoteHelper ::
|
||||||
:--> PStakeRedeemerHandler
|
:--> PStakeRedeemerHandler
|
||||||
)
|
)
|
||||||
pvoteHelper = phoistAcyclic $
|
pvoteHelper = phoistAcyclic $
|
||||||
plam $ \valProposalCtx ctx -> unTermCont $ do
|
plam $ \valProposalCtx ctx ->
|
||||||
pguardC "Owner or delegate signs this transaction" $
|
|
||||||
pisSignedBy # pconstant True # ctx
|
|
||||||
|
|
||||||
-- This puts trust into the Proposal. The Proposal must necessarily check
|
-- This puts trust into the Proposal. The Proposal must necessarily check
|
||||||
-- that this is not abused.
|
-- that this is not abused.
|
||||||
|
passert
|
||||||
pguardC "Correct outputs" $
|
"Correct outputs"
|
||||||
ponlyLocksUpdated # (valProposalCtx # ctx) # ctx
|
(ponlyLocksUpdated # (valProposalCtx # ctx) # ctx)
|
||||||
|
(pconstant ())
|
||||||
pure $ pconstant ()
|
|
||||||
|
|
||||||
-- | Add new lock the the existing list of locked.
|
-- | Add new lock the the existing list of locked.
|
||||||
paddNewLock ::
|
paddNewLock ::
|
||||||
|
|
@ -199,33 +204,60 @@ ppermitVote = pvoteHelper #$ phoistAcyclic $
|
||||||
pguardC "Only one stake input allowed" $
|
pguardC "Only one stake input allowed" $
|
||||||
pisSingleton # ctxF.stakeInputDatums
|
pisSingleton # ctxF.stakeInputDatums
|
||||||
|
|
||||||
|
pguardC "Owner signs this transaction" $
|
||||||
|
pisSignedBy # pconstant False # ctx
|
||||||
|
|
||||||
pure lock
|
pure lock
|
||||||
|
|
||||||
pure $
|
pure $
|
||||||
paddNewLock #$ pmatch ctxF.proposalContext $ \case
|
paddNewLock #$ pmatch ctxF.proposalContext $ \case
|
||||||
PSpendProposal pid _ r -> pmatch r $ \case
|
PSpendProposal proposal redeemer currentTime -> unTermCont $ do
|
||||||
PVote ((pfromData . (pfield @"resultTag" #)) -> voteFor) ->
|
mkLock <- pletC $
|
||||||
mkRecordConstr
|
plam $ \action ->
|
||||||
PVoted
|
mkRecordConstr
|
||||||
( #votedOn
|
PProposalLock
|
||||||
.= pdata pid
|
( #proposalId
|
||||||
.& #votedFor
|
.= pfield @"proposalId"
|
||||||
.= pdata voteFor
|
# proposal
|
||||||
)
|
.& #action
|
||||||
PCosign _ ->
|
.= pdata action
|
||||||
withOnlyOneStakeInput
|
|
||||||
#$ mkRecordConstr
|
|
||||||
PCosigned
|
|
||||||
( #cosigned .= pdata pid
|
|
||||||
)
|
)
|
||||||
_ -> ptraceError "Expected Vote"
|
|
||||||
PNewProposal pid ->
|
pure $
|
||||||
withOnlyOneStakeInput
|
pmatch redeemer $ \case
|
||||||
#$ mkRecordConstr
|
PVote ((pfromData . (pfield @"resultTag" #)) -> voteFor) ->
|
||||||
PCreated
|
unTermCont $ do
|
||||||
( #created .= pdata pid
|
pguardC "Owner or delegatee signs the transaction" $
|
||||||
)
|
pisSignedBy # pconstant True # ctx
|
||||||
_ -> ptraceError "Expected proposal"
|
|
||||||
|
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
|
data PRemoveLocksMode (s :: S) = PRemoveVoterLockOnly | PRemoveAllLocks
|
||||||
deriving stock (Generic)
|
deriving stock (Generic)
|
||||||
|
|
@ -235,33 +267,59 @@ instance DerivePlutusType PRemoveLocksMode where
|
||||||
type DPTStrat _ = PlutusTypeScott
|
type DPTStrat _ = PlutusTypeScott
|
||||||
|
|
||||||
{- | Remove stake locks with the proposal id given the list of existing locks.
|
{- | 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 ::
|
premoveLocks ::
|
||||||
forall (s :: S).
|
forall (s :: S).
|
||||||
Term
|
Term
|
||||||
s
|
s
|
||||||
( PProposalId
|
( PProposalId
|
||||||
|
:--> PMaybe PPOSIXTime
|
||||||
|
:--> PProposalTime
|
||||||
:--> PRemoveLocksMode
|
:--> PRemoveLocksMode
|
||||||
:--> PBuiltinList (PAsData PProposalLock)
|
:--> PBuiltinList (PAsData PProposalLock)
|
||||||
:--> PBuiltinList (PAsData PProposalLock)
|
:--> PBuiltinList (PAsData PProposalLock)
|
||||||
)
|
)
|
||||||
premoveLocks = phoistAcyclic $
|
premoveLocks =
|
||||||
plam $ \pid rl -> unTermCont $ do
|
phoistAcyclic $
|
||||||
shouldRemoveOtherLocks <- pletC $
|
plam $ \proposalId unlockCooldown currentTime mode -> unTermCont $ do
|
||||||
plam $ \pid' ->
|
shouldRemoveAllLocks <- pletC $ mode #== pcon PRemoveAllLocks
|
||||||
pid' #== pid #&& rl #== pcon PRemoveAllLocks
|
|
||||||
|
|
||||||
pure $
|
PCurrentTime lowerBound _ <- pmatchC currentTime
|
||||||
pfilter
|
|
||||||
# plam
|
let handleVoter
|
||||||
( \(pfromData -> l) -> pnot #$ pmatch l $ \case
|
( (pfield @"createdAt" #) ->
|
||||||
PCosigned ((pfield @"cosigned" #) -> pid') ->
|
createdAt
|
||||||
shouldRemoveOtherLocks # pid'
|
) =
|
||||||
PCreated ((pfield @"created" #) -> pid') ->
|
let notInCooldown =
|
||||||
shouldRemoveOtherLocks # pid'
|
pmaybe
|
||||||
PVoted ((pfield @"votedOn" #) -> pid') -> pid' #== pid
|
# 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'.
|
{- | Default implementation of 'Agora.Stake.RetractVotes'.
|
||||||
|
|
||||||
|
|
@ -269,17 +327,41 @@ premoveLocks = phoistAcyclic $
|
||||||
-}
|
-}
|
||||||
pretractVote :: forall (s :: S). Term s PStakeRedeemerHandler
|
pretractVote :: forall (s :: S). Term s PStakeRedeemerHandler
|
||||||
pretractVote = pvoteHelper #$ phoistAcyclic $
|
pretractVote = pvoteHelper #$ phoistAcyclic $
|
||||||
plam $
|
plam $ \ctx ->
|
||||||
flip pmatch $ \ctxF ->
|
pmatch ctx $ \ctxF ->
|
||||||
pmatch ctxF.proposalContext $ \case
|
pmatch ctxF.proposalContext $ \case
|
||||||
PSpendProposal pid s r -> pmatch r $ \case
|
PSpendProposal proposal redeemer currentTime -> pmatch redeemer $ \case
|
||||||
PUnlockStake _ ->
|
PUnlockStake _ -> unTermCont $ do
|
||||||
let mode =
|
proposalF <-
|
||||||
pif
|
pletFieldsC
|
||||||
(s #== pconstant Finished)
|
@'[ "proposalId"
|
||||||
(pcon PRemoveAllLocks)
|
, "status"
|
||||||
(pcon PRemoveVoterLockOnly)
|
, "timingConfig"
|
||||||
in premoveLocks # pid # mode
|
]
|
||||||
|
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 unlock"
|
||||||
_ -> ptraceError "Expected spending proposal"
|
_ -> ptraceError "Expected spending proposal"
|
||||||
|
|
||||||
|
|
@ -387,12 +469,12 @@ pdepositWithdraw = phoistAcyclic $
|
||||||
stakeInputDatum <-
|
stakeInputDatum <-
|
||||||
pletC $
|
pletC $
|
||||||
ptrace "Single stake input" $
|
ptrace "Single stake input" $
|
||||||
pfromSingleton # ctxF.stakeInputDatums
|
ptryFromSingleton # ctxF.stakeInputDatums
|
||||||
stakeInputDatumF <- pletAllC stakeInputDatum
|
stakeInputDatumF <- pletAllC stakeInputDatum
|
||||||
|
|
||||||
let stakeOutputDatum =
|
let stakeOutputDatum =
|
||||||
ptrace "Single stake output" $
|
ptrace "Single stake output" $
|
||||||
pfromSingleton # ctxF.stakeOutputDatums
|
ptryFromSingleton # ctxF.stakeOutputDatums
|
||||||
|
|
||||||
----------------------------------------------------------------------------
|
----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ module Agora.Stake.Scripts (
|
||||||
|
|
||||||
import Agora.Credential (authorizationContext, pauthorizedBy)
|
import Agora.Credential (authorizationContext, pauthorizedBy)
|
||||||
import Agora.Proposal (PProposalDatum, PProposalRedeemer)
|
import Agora.Proposal (PProposalDatum, PProposalRedeemer)
|
||||||
|
import Agora.Proposal.Time (pcurrentProposalTime)
|
||||||
|
import Agora.SafeMoney (GTTag, ProposalSTTag, StakeSTTag)
|
||||||
import Agora.Stake (
|
import Agora.Stake (
|
||||||
PProposalContext (
|
PProposalContext (
|
||||||
PNewProposal,
|
PNewProposal,
|
||||||
|
|
@ -52,13 +54,7 @@ import Agora.Stake.Redeemers (
|
||||||
ppermitVote,
|
ppermitVote,
|
||||||
pretractVote,
|
pretractVote,
|
||||||
)
|
)
|
||||||
import Agora.Utils (
|
import Agora.Utils (pisDNothing, ptoScottEncodingT, puntag)
|
||||||
passert,
|
|
||||||
pisDNothing,
|
|
||||||
pmapMaybe,
|
|
||||||
psymbolValueOf',
|
|
||||||
pvalidatorHashToTokenName,
|
|
||||||
)
|
|
||||||
import Plutarch.Api.V1 (
|
import Plutarch.Api.V1 (
|
||||||
PCredential (PPubKeyCredential, PScriptCredential),
|
PCredential (PPubKeyCredential, PScriptCredential),
|
||||||
PCurrencySymbol,
|
PCurrencySymbol,
|
||||||
|
|
@ -77,13 +73,14 @@ import Plutarch.Extra.AssetClass (
|
||||||
PAssetClass,
|
PAssetClass,
|
||||||
PAssetClassData,
|
PAssetClassData,
|
||||||
passetClass,
|
passetClass,
|
||||||
ptoScottEncoding,
|
|
||||||
)
|
)
|
||||||
|
import Plutarch.Extra.Bool (passert)
|
||||||
import Plutarch.Extra.Field (pletAll, pletAllC)
|
import Plutarch.Extra.Field (pletAll, pletAllC)
|
||||||
import Plutarch.Extra.Functor (PFunctor (pfmap))
|
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 (
|
import Plutarch.Extra.Maybe (
|
||||||
passertPJust,
|
passertPJust,
|
||||||
|
pdjust,
|
||||||
pfromJust,
|
pfromJust,
|
||||||
pfromMaybe,
|
pfromMaybe,
|
||||||
pjust,
|
pjust,
|
||||||
|
|
@ -93,9 +90,12 @@ import Plutarch.Extra.Maybe (
|
||||||
import Plutarch.Extra.Ord (POrdering (PEQ, PGT, PLT), pcompareBy, pfromOrd)
|
import Plutarch.Extra.Ord (POrdering (PEQ, PGT, PLT), pcompareBy, pfromOrd)
|
||||||
import Plutarch.Extra.ScriptContext (
|
import Plutarch.Extra.ScriptContext (
|
||||||
pfindTxInByTxOutRef,
|
pfindTxInByTxOutRef,
|
||||||
pfromOutputDatum,
|
ptryFromOutputDatum,
|
||||||
|
pvalidatorHashFromAddress,
|
||||||
|
pvalidatorHashToTokenName,
|
||||||
pvalueSpent,
|
pvalueSpent,
|
||||||
)
|
)
|
||||||
|
import Plutarch.Extra.Tagged (PTagged)
|
||||||
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (
|
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (
|
||||||
pguardC,
|
pguardC,
|
||||||
pletC,
|
pletC,
|
||||||
|
|
@ -105,7 +105,9 @@ import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (
|
||||||
)
|
)
|
||||||
import Plutarch.Extra.Value (
|
import Plutarch.Extra.Value (
|
||||||
passetClassValueOf,
|
passetClassValueOf,
|
||||||
|
passetClassValueOfT,
|
||||||
psymbolValueOf,
|
psymbolValueOf,
|
||||||
|
psymbolValueOf',
|
||||||
)
|
)
|
||||||
import Plutarch.Num (PNum (pnegate))
|
import Plutarch.Num (PNum (pnegate))
|
||||||
import Plutarch.Unsafe (punsafeCoerce)
|
import Plutarch.Unsafe (punsafeCoerce)
|
||||||
|
|
@ -131,15 +133,14 @@ import Prelude hiding (Num ((+)))
|
||||||
== Arguments
|
== Arguments
|
||||||
|
|
||||||
Following arguments should be provided(in this order):
|
Following arguments should be provided(in this order):
|
||||||
1. governor ST assetclass
|
1. governance token assetclass
|
||||||
|
|
||||||
@since 1.0.0
|
@since 1.0.0
|
||||||
-}
|
-}
|
||||||
stakePolicy ::
|
stakePolicy ::
|
||||||
-- | The (governance) token that a Stake can store.
|
ClosedTerm (PTagged GTTag PAssetClassData :--> PMintingPolicy)
|
||||||
ClosedTerm (PAssetClassData :--> PMintingPolicy)
|
|
||||||
stakePolicy =
|
stakePolicy =
|
||||||
plam $ \gstClass _redeemer ctx' -> unTermCont $ do
|
plam $ \gtClass _redeemer ctx' -> unTermCont $ do
|
||||||
ctx <- pletFieldsC @'["txInfo", "purpose"] ctx'
|
ctx <- pletFieldsC @'["txInfo", "purpose"] ctx'
|
||||||
txInfo <- pletC $ ctx.txInfo
|
txInfo <- pletC $ ctx.txInfo
|
||||||
let _a :: Term _ PTxInfo
|
let _a :: Term _ PTxInfo
|
||||||
|
|
@ -197,7 +198,7 @@ stakePolicy =
|
||||||
datumF <-
|
datumF <-
|
||||||
pletAllC $
|
pletAllC $
|
||||||
pfromData $
|
pfromData $
|
||||||
pfromOutputDatum @(PAsData PStakeDatum)
|
ptryFromOutputDatum @(PAsData PStakeDatum)
|
||||||
# outputF.datum
|
# outputF.datum
|
||||||
# txInfoF.datums
|
# txInfoF.datums
|
||||||
|
|
||||||
|
|
@ -205,10 +206,10 @@ stakePolicy =
|
||||||
foldl1
|
foldl1
|
||||||
(#&&)
|
(#&&)
|
||||||
[ ptraceIfFalse "Stake ouput has expected amount of stake token" $
|
[ ptraceIfFalse "Stake ouput has expected amount of stake token" $
|
||||||
passetClassValueOf
|
passetClassValueOfT
|
||||||
# (ptoScottEncoding # gstClass)
|
# (ptoScottEncodingT # gtClass)
|
||||||
# outputF.value
|
# outputF.value
|
||||||
#== pto (pfromData datumF.stakedAmount)
|
#== pfromData datumF.stakedAmount
|
||||||
, ptraceIfFalse "Stake Owner should sign the transaction" $
|
, ptraceIfFalse "Stake Owner should sign the transaction" $
|
||||||
pauthorizedBy
|
pauthorizedBy
|
||||||
# authorizationContext txInfoF
|
# authorizationContext txInfoF
|
||||||
|
|
@ -232,17 +233,17 @@ stakePolicy =
|
||||||
Following arguments should be provided(in this order):
|
Following arguments should be provided(in this order):
|
||||||
1. stake ST symbol
|
1. stake ST symbol
|
||||||
2. proposal ST assetclass
|
2. proposal ST assetclass
|
||||||
3. governor ST assetclass
|
3. governance token assetclass
|
||||||
|
|
||||||
@since 1.0.0
|
@since 1.0.0
|
||||||
-}
|
-}
|
||||||
mkStakeValidator ::
|
mkStakeValidator ::
|
||||||
StakeRedeemerImpl s ->
|
StakeRedeemerImpl s ->
|
||||||
Term s PCurrencySymbol ->
|
Term s (PTagged StakeSTTag PCurrencySymbol) ->
|
||||||
Term s PAssetClass ->
|
Term s (PTagged ProposalSTTag PAssetClass) ->
|
||||||
Term s PAssetClass ->
|
Term s (PTagged GTTag PAssetClass) ->
|
||||||
Term s PValidator
|
Term s PValidator
|
||||||
mkStakeValidator impl sstSymbol pstClass gstClass =
|
mkStakeValidator impl sstSymbol pstClass gtClass =
|
||||||
plam $ \_datum redeemer ctx -> unTermCont $ do
|
plam $ \_datum redeemer ctx -> unTermCont $ do
|
||||||
ctxF <- pletFieldsC @'["txInfo", "purpose"] ctx
|
ctxF <- pletFieldsC @'["txInfo", "purpose"] ctx
|
||||||
txInfo <- pletC $ pfromData ctxF.txInfo
|
txInfo <- pletC $ pfromData ctxF.txInfo
|
||||||
|
|
@ -256,6 +257,7 @@ mkStakeValidator impl sstSymbol pstClass gstClass =
|
||||||
, "signatories"
|
, "signatories"
|
||||||
, "redeemers"
|
, "redeemers"
|
||||||
, "datums"
|
, "datums"
|
||||||
|
, "validRange"
|
||||||
]
|
]
|
||||||
txInfo
|
txInfo
|
||||||
|
|
||||||
|
|
@ -271,18 +273,16 @@ mkStakeValidator impl sstSymbol pstClass gstClass =
|
||||||
# (pfield @"_0" # stakeInputRef)
|
# (pfield @"_0" # stakeInputRef)
|
||||||
# txInfoF.inputs
|
# txInfoF.inputs
|
||||||
|
|
||||||
stakeValidatorCredential <-
|
stakeValidatorHash <-
|
||||||
pletC $
|
pletC $
|
||||||
pfield @"credential"
|
pfromJust
|
||||||
|
#$ pvalidatorHashFromAddress
|
||||||
#$ pfield @"address"
|
#$ pfield @"address"
|
||||||
# validatedInput
|
# validatedInput
|
||||||
|
|
||||||
let sstName = pvalidatorHashToTokenName #$ pmatch stakeValidatorCredential $
|
let sstName = pvalidatorHashToTokenName stakeValidatorHash
|
||||||
\case
|
|
||||||
PScriptCredential r -> pfield @"_0" # r
|
|
||||||
_ -> perror
|
|
||||||
|
|
||||||
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"
|
PGT -> ptraceError "More than one SST in one UTxO"
|
||||||
-- 1
|
-- 1
|
||||||
PEQ ->
|
PEQ ->
|
||||||
let ownerCredential = pfield @"credential" # txOutF.address
|
let ownerValidatoHash =
|
||||||
|
pfromJust
|
||||||
|
#$ pvalidatorHashFromAddress
|
||||||
|
# txOutF.address
|
||||||
|
|
||||||
isOwnedByStakeValidator =
|
isOwnedByStakeValidator =
|
||||||
ownerCredential #== stakeValidatorCredential
|
ownerValidatoHash #== stakeValidatorHash
|
||||||
|
|
||||||
datum =
|
datum =
|
||||||
ptrace "Resolve stake datum" $
|
ptrace "Resolve stake datum" $
|
||||||
pfromData $
|
pfromData $
|
||||||
pfromOutputDatum @(PAsData PStakeDatum)
|
ptryFromOutputDatum @(PAsData PStakeDatum)
|
||||||
# txOutF.datum
|
# txOutF.datum
|
||||||
# txInfoF.datums
|
# txInfoF.datums
|
||||||
in passert
|
in passert
|
||||||
|
|
@ -342,7 +345,7 @@ mkStakeValidator impl sstSymbol pstClass gstClass =
|
||||||
|
|
||||||
authorizedBy <- pletC $ pauthorizedBy # authorizationContext txInfoF
|
authorizedBy <- pletC $ pauthorizedBy # authorizationContext txInfoF
|
||||||
|
|
||||||
PPair allHaveSameOwner allHaveSameDelegatee <-
|
PPair allHaveSameOwner allHaveSameOrOwnedByDelegatee <-
|
||||||
pmatchC $
|
pmatchC $
|
||||||
pfoldr
|
pfoldr
|
||||||
# plam
|
# plam
|
||||||
|
|
@ -355,11 +358,15 @@ mkStakeValidator impl sstSymbol pstClass gstClass =
|
||||||
allHaveSameOwner
|
allHaveSameOwner
|
||||||
#&& dF.owner
|
#&& dF.owner
|
||||||
#== firstStakeInputDatumF.owner
|
#== firstStakeInputDatumF.owner
|
||||||
allHaveSameDelegatee' =
|
allHaveSameOrOwnedByDelegatee' =
|
||||||
allHaveSameDelegatee
|
let delegated =
|
||||||
#&& dF.delegatedTo
|
dF.delegatedTo #== firstStakeInputDatumF.delegatedTo
|
||||||
#== firstStakeInputDatumF.delegatedTo
|
ownedByDelegatee =
|
||||||
in pcon $ PPair allHaveSameOwner' allHaveSameDelegatee'
|
pdata (pdjust # dF.owner)
|
||||||
|
#== firstStakeInputDatumF.delegatedTo
|
||||||
|
in allHaveSameDelegatee
|
||||||
|
#&& (delegated #|| ownedByDelegatee)
|
||||||
|
in pcon $ PPair allHaveSameOwner' allHaveSameOrOwnedByDelegatee'
|
||||||
)
|
)
|
||||||
# pcon (PPair (pconstant True) (pconstant True))
|
# pcon (PPair (pconstant True) (pconstant True))
|
||||||
# restOfStakeInputDatums
|
# restOfStakeInputDatums
|
||||||
|
|
@ -370,7 +377,7 @@ mkStakeValidator impl sstSymbol pstClass gstClass =
|
||||||
# firstStakeInputDatumF.owner
|
# firstStakeInputDatumF.owner
|
||||||
|
|
||||||
delegateSignsTransaction =
|
delegateSignsTransaction =
|
||||||
allHaveSameDelegatee
|
allHaveSameOrOwnedByDelegatee
|
||||||
#&& pmaybeData
|
#&& pmaybeData
|
||||||
# pconstant False
|
# pconstant False
|
||||||
# plam ((authorizedBy #) . pfromData)
|
# plam ((authorizedBy #) . pfromData)
|
||||||
|
|
@ -407,13 +414,12 @@ mkStakeValidator impl sstSymbol pstClass gstClass =
|
||||||
( \output ->
|
( \output ->
|
||||||
let validateGT = plam $ \stakeDatum ->
|
let validateGT = plam $ \stakeDatum ->
|
||||||
let expected =
|
let expected =
|
||||||
pto $
|
pfromData $
|
||||||
pfromData $
|
pfield @"stakedAmount" # stakeDatum
|
||||||
pfield @"stakedAmount" # stakeDatum
|
|
||||||
|
|
||||||
actual =
|
actual =
|
||||||
passetClassValueOf
|
passetClassValueOfT
|
||||||
# gstClass
|
# gtClass
|
||||||
# (pfield @"value" # output)
|
# (pfield @"value" # output)
|
||||||
in pif
|
in pif
|
||||||
(expected #== actual)
|
(expected #== actual)
|
||||||
|
|
@ -433,19 +439,20 @@ mkStakeValidator impl sstSymbol pstClass gstClass =
|
||||||
plam $
|
plam $
|
||||||
flip pletAll $ \txOutF ->
|
flip pletAll $ \txOutF ->
|
||||||
let isProposalUTxO =
|
let isProposalUTxO =
|
||||||
passetClassValueOf
|
passetClassValueOfT
|
||||||
# pstClass
|
# pstClass
|
||||||
# txOutF.value
|
# txOutF.value
|
||||||
#== 1
|
#== 1
|
||||||
|
|
||||||
proposalDatum =
|
proposalDatum =
|
||||||
pfromData $
|
pfromData $
|
||||||
pfromOutputDatum @(PAsData PProposalDatum)
|
ptryFromOutputDatum @(PAsData PProposalDatum)
|
||||||
# txOutF.datum
|
# txOutF.datum
|
||||||
# txInfoF.datums
|
# txInfoF.datums
|
||||||
in pif isProposalUTxO (pjust # proposalDatum) pnothing
|
in pif isProposalUTxO (pjust # proposalDatum) pnothing
|
||||||
|
|
||||||
let pstMinted =
|
let pstMinted =
|
||||||
passetClassValueOf # pstClass # txInfoF.mint #== 1
|
passetClassValueOfT # pstClass # txInfoF.mint #== 1
|
||||||
|
|
||||||
newProposalContext =
|
newProposalContext =
|
||||||
pcon $
|
pcon $
|
||||||
|
|
@ -477,10 +484,13 @@ mkStakeValidator impl sstSymbol pstClass gstClass =
|
||||||
pfmap
|
pfmap
|
||||||
# plam
|
# plam
|
||||||
( \proposalDatum ->
|
( \proposalDatum ->
|
||||||
let id = pfield @"proposalId" # proposalDatum
|
let redeemer = getProposalRedeemer # inInfoF.outRef
|
||||||
status = pfield @"status" # proposalDatum
|
currentTime =
|
||||||
redeemer = getProposalRedeemer # inInfoF.outRef
|
passertPJust
|
||||||
in pcon $ PSpendProposal id status redeemer
|
# "Should resolve proposal time"
|
||||||
|
#$ pcurrentProposalTime
|
||||||
|
# txInfoF.validRange
|
||||||
|
in pcon $ PSpendProposal proposalDatum redeemer currentTime
|
||||||
)
|
)
|
||||||
#$ getProposalDatum
|
#$ getProposalDatum
|
||||||
# pfromData inInfoF.resolved
|
# pfromData inInfoF.resolved
|
||||||
|
|
@ -598,15 +608,15 @@ mkStakeValidator impl sstSymbol pstClass gstClass =
|
||||||
Following arguments should be provided(in this order):
|
Following arguments should be provided(in this order):
|
||||||
1. stake ST symbol
|
1. stake ST symbol
|
||||||
2. proposal ST assetclass
|
2. proposal ST assetclass
|
||||||
3. governor ST assetclass
|
3. governance token assetclass
|
||||||
|
|
||||||
@since 1.0.0
|
@since 1.0.0
|
||||||
-}
|
-}
|
||||||
stakeValidator ::
|
stakeValidator ::
|
||||||
ClosedTerm
|
ClosedTerm
|
||||||
( PCurrencySymbol
|
( PTagged StakeSTTag PCurrencySymbol
|
||||||
:--> PAssetClassData
|
:--> PTagged ProposalSTTag PAssetClassData
|
||||||
:--> PAssetClassData
|
:--> PTagged GTTag PAssetClassData
|
||||||
:--> PValidator
|
:--> PValidator
|
||||||
)
|
)
|
||||||
stakeValidator =
|
stakeValidator =
|
||||||
|
|
@ -622,5 +632,5 @@ stakeValidator =
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
sstSymbol
|
sstSymbol
|
||||||
(ptoScottEncoding # pstClass)
|
(ptoScottEncodingT # pstClass)
|
||||||
(ptoScottEncoding # gstClass)
|
(ptoScottEncodingT # gstClass)
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,10 @@ module Agora.Treasury (
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Agora.AuthorityToken (singleAuthorityTokenBurned)
|
import Agora.AuthorityToken (singleAuthorityTokenBurned)
|
||||||
|
import Agora.SafeMoney (AuthorityTokenTag)
|
||||||
import Plutarch.Api.V1.Value (PCurrencySymbol, PValue)
|
import Plutarch.Api.V1.Value (PCurrencySymbol, PValue)
|
||||||
import Plutarch.Api.V2 (PScriptPurpose (PSpending), PValidator)
|
import Plutarch.Api.V2 (PScriptPurpose (PSpending), PValidator)
|
||||||
|
import Plutarch.Extra.Tagged (PTagged)
|
||||||
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pguardC, pletFieldsC, pmatchC)
|
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pguardC, pletFieldsC, pmatchC)
|
||||||
|
|
||||||
{- | Validator ensuring that transactions consuming the treasury
|
{- | 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):
|
Following arguments should be provided(in this order):
|
||||||
1. authority token symbol
|
1. authority token symbol
|
||||||
|
|
||||||
@since 0.1.0
|
@since 1.0.0
|
||||||
-}
|
-}
|
||||||
treasuryValidator ::
|
treasuryValidator ::
|
||||||
ClosedTerm (PCurrencySymbol :--> PValidator)
|
ClosedTerm (PTagged AuthorityTokenTag PCurrencySymbol :--> PValidator)
|
||||||
treasuryValidator = plam $ \atSymbol _ _ ctx' -> unTermCont $ do
|
treasuryValidator = plam $ \atSymbol _ _ ctx' -> unTermCont $ do
|
||||||
-- plet required fields from script context.
|
-- plet required fields from script context.
|
||||||
ctx <- pletFieldsC @["txInfo", "purpose"] ctx'
|
ctx <- pletFieldsC @["txInfo", "purpose"] ctx'
|
||||||
|
|
|
||||||
|
|
@ -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.
|
Plutarch utility functions that should be upstreamed or don't belong anywhere else.
|
||||||
-}
|
-}
|
||||||
module Agora.Utils (
|
module Agora.Utils (
|
||||||
validatorHashToTokenName,
|
|
||||||
validatorHashToAddress,
|
validatorHashToAddress,
|
||||||
pltAsData,
|
|
||||||
withBuiltinPairAsData,
|
|
||||||
pvalidatorHashToTokenName,
|
|
||||||
pscriptHashToTokenName,
|
|
||||||
scriptHashToTokenName,
|
|
||||||
plistEqualsBy,
|
|
||||||
pstringIntercalate,
|
pstringIntercalate,
|
||||||
punwords,
|
punwords,
|
||||||
pcurrentTimeDuration,
|
|
||||||
pdelete,
|
|
||||||
pdeleteBy,
|
|
||||||
pmustDeleteBy,
|
|
||||||
pisSingleton,
|
|
||||||
pfromSingleton,
|
|
||||||
pmapMaybe,
|
|
||||||
PAlternative (..),
|
|
||||||
ppureIf,
|
|
||||||
pltBy,
|
|
||||||
pinsertUniqueBy,
|
|
||||||
ptryFromRedeemer,
|
|
||||||
passert,
|
|
||||||
pisNothing,
|
pisNothing,
|
||||||
pisDNothing,
|
pisDNothing,
|
||||||
psymbolValueOf',
|
ptoScottEncodingT,
|
||||||
|
ptaggedSymbolValueOf,
|
||||||
|
ptag,
|
||||||
|
puntag,
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Plutarch.Api.V1 (
|
|
||||||
KeyGuarantees (Unsorted),
|
|
||||||
PPOSIXTime,
|
|
||||||
PRedeemer,
|
|
||||||
PValidatorHash,
|
|
||||||
)
|
|
||||||
import Plutarch.Api.V1.AssocMap (PMap, plookup)
|
|
||||||
import Plutarch.Api.V2 (
|
import Plutarch.Api.V2 (
|
||||||
AmountGuarantees,
|
AmountGuarantees,
|
||||||
|
KeyGuarantees,
|
||||||
PCurrencySymbol,
|
PCurrencySymbol,
|
||||||
PMaybeData (PDNothing),
|
PMaybeData (PDNothing),
|
||||||
PScriptHash,
|
|
||||||
PScriptPurpose,
|
|
||||||
PTokenName,
|
|
||||||
PValue,
|
PValue,
|
||||||
)
|
)
|
||||||
import Plutarch.Extra.Applicative (PApplicative (ppure))
|
import Plutarch.Extra.AssetClass (PAssetClass, PAssetClassData, ptoScottEncoding)
|
||||||
import Plutarch.Extra.Category (PCategory (pidentity))
|
import Plutarch.Extra.Tagged (PTagged)
|
||||||
import Plutarch.Extra.Functor (PFunctor (PSubcategory, pfmap))
|
import Plutarch.Extra.Value (psymbolValueOf)
|
||||||
import Plutarch.Extra.Maybe (pjust, pnothing)
|
import Plutarch.Unsafe (punsafeDowncast)
|
||||||
import Plutarch.Extra.Ord (PComparator, POrdering (PLT), pcompareBy, pequateBy)
|
|
||||||
import Plutarch.Extra.Time (PCurrentTime (PCurrentTime))
|
|
||||||
import Plutarch.Unsafe (punsafeCoerce)
|
|
||||||
import PlutusLedgerApi.V2 (
|
import PlutusLedgerApi.V2 (
|
||||||
Address (Address),
|
Address (Address),
|
||||||
Credential (ScriptCredential),
|
Credential (ScriptCredential),
|
||||||
ScriptHash (ScriptHash),
|
ValidatorHash,
|
||||||
TokenName (TokenName),
|
|
||||||
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'.
|
{- | Create an 'Address' from a given 'ValidatorHash' with no 'PlutusLedgerApi.V1.Credential.StakingCredential'.
|
||||||
|
|
||||||
@since 0.1.0
|
@since 0.1.0
|
||||||
|
|
@ -110,62 +43,6 @@ pscriptHashToTokenName = punsafeCoerce
|
||||||
validatorHashToAddress :: ValidatorHash -> Address
|
validatorHashToAddress :: ValidatorHash -> Address
|
||||||
validatorHashToAddress vh = Address (ScriptCredential vh) Nothing
|
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
|
-- | @since 1.0.0
|
||||||
pstringIntercalate ::
|
pstringIntercalate ::
|
||||||
forall (s :: S).
|
forall (s :: S).
|
||||||
|
|
@ -183,225 +60,6 @@ punwords ::
|
||||||
Term s PString
|
Term s PString
|
||||||
punwords = pstringIntercalate " "
|
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
|
-- | @since 1.0.0
|
||||||
pisNothing ::
|
pisNothing ::
|
||||||
forall (a :: PType) (s :: S).
|
forall (a :: PType) (s :: S).
|
||||||
|
|
@ -422,45 +80,38 @@ pisDNothing = phoistAcyclic $
|
||||||
PDNothing _ -> pconstant True
|
PDNothing _ -> pconstant True
|
||||||
_ -> pconstant False
|
_ -> pconstant False
|
||||||
|
|
||||||
{- | Get the negative and positive amount of a particular 'CurrencySymbol', and
|
-- | @since 1.0.0
|
||||||
return nothing if it doesn't exist in the value.
|
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
|
@since 1.0.0
|
||||||
-}
|
-}
|
||||||
psymbolValueOf' ::
|
ptaggedSymbolValueOf ::
|
||||||
forall
|
forall
|
||||||
|
{k :: Type}
|
||||||
|
(unit :: k)
|
||||||
(keys :: KeyGuarantees)
|
(keys :: KeyGuarantees)
|
||||||
(amounts :: AmountGuarantees)
|
(amounts :: AmountGuarantees)
|
||||||
(s :: S).
|
(s :: S).
|
||||||
Term
|
Term s (PTagged unit PCurrencySymbol :--> (PValue keys amounts :--> PInteger))
|
||||||
s
|
ptaggedSymbolValueOf = phoistAcyclic $ plam $ \tcs -> psymbolValueOf # pto tcs
|
||||||
( PCurrencySymbol
|
|
||||||
:--> PValue keys amounts
|
-- | @since 1.0.0
|
||||||
:--> PMaybe
|
ptag ::
|
||||||
( PPair
|
forall {k :: Type} (tag :: k) (a :: PType) (s :: S).
|
||||||
-- Positive amount
|
Term s a ->
|
||||||
PInteger
|
Term s (PTagged tag a)
|
||||||
-- Negative amount
|
ptag = punsafeDowncast
|
||||||
PInteger
|
|
||||||
)
|
-- | @since 1.0.0
|
||||||
)
|
puntag ::
|
||||||
psymbolValueOf' = phoistAcyclic $
|
forall {k :: Type} (tag :: k) (a :: PType) (s :: S).
|
||||||
plam $ \sym value ->
|
Term s (PTagged tag a) ->
|
||||||
let tnMap = plookup # sym # pto value
|
Term s a
|
||||||
f =
|
puntag = pto
|
||||||
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
|
|
||||||
|
|
|
||||||
984
bench.csv
984
bench.csv
|
|
@ -1,483 +1,503 @@
|
||||||
name,cpu,mem,size
|
name,cpu,mem,size
|
||||||
Agora/Effects/Treasury Withdrawal Effect/effect/Simple,216491233,584406,3880
|
Agora/Effects/Treasury Withdrawal Effect/effect/Simple,217066233,586906,3885
|
||||||
Agora/Effects/Treasury Withdrawal Effect/effect/Simple with multiple treasuries ,307752363,787074,4312
|
Agora/Effects/Treasury Withdrawal Effect/effect/Simple with multiple treasuries ,308925363,792174,4317
|
||||||
Agora/Effects/Treasury Withdrawal Effect/effect/Mixed Assets,300492604,786706,4250
|
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,124187615,349163,11718
|
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,145816056,387807,4684
|
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,3556
|
Agora/Stake/policy/create/valid/stake owner: pub key,77468330,198844,3625
|
||||||
Agora/Stake/policy/create/valid/stake owner: script,90607586,237423,3591
|
Agora/Stake/policy/create/valid/stake owner: script,90607586,237423,3660
|
||||||
Agora/Stake/validator/destroy/legal/One stake/stake validator,100147548,269527,7240
|
Agora/Stake/validator/destroy/legal/One stake/stake validator,100744620,274835,8167
|
||||||
Agora/Stake/validator/destroy/legal/One stake/stake policy,29665872,85956,3543
|
Agora/Stake/validator/destroy/legal/One stake/stake policy,29665872,85956,3612
|
||||||
Agora/Stake/validator/destroy/legal/Multiple stake/stake validator,653259180,1567111,10493
|
Agora/Stake/validator/destroy/legal/Multiple stake/stake validator,639511701,1565246,11420
|
||||||
Agora/Stake/validator/destroy/legal/Multiple stake/stake policy,292337523,820464,6795
|
Agora/Stake/validator/destroy/legal/Multiple stake/stake policy,292337523,820464,6864
|
||||||
Agora/Stake/validator/destroy/illegal/Destroy locked stakes/stake policy,292337523,820464,6856
|
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,6764
|
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,6795
|
Agora/Stake/validator/destroy/illegal/not authorized by owner/stake policy,292337523,820464,6864
|
||||||
Agora/Stake/validator/stakeDepositWithdraw deposit,142600267,368376,7355
|
Agora/Stake/validator/stakeDepositWithdraw deposit,139642477,368480,8282
|
||||||
Agora/Stake/validator/stakeDepositWithdraw withdraw,142600267,368376,7347
|
Agora/Stake/validator/stakeDepositWithdraw withdraw,139642477,368480,8274
|
||||||
Agora/Stake/validator/set delegate/override existing delegate,174762504,439707,7486
|
Agora/Stake/validator/set delegate/override existing delegate,171170225,438309,8413
|
||||||
Agora/Stake/validator/set delegate/remove existing delegate,164862019,415117,7416
|
Agora/Stake/validator/set delegate/remove existing delegate,161835229,414921,8343
|
||||||
Agora/Stake/validator/set delegate/set delegate to something,172333516,432607,7416
|
Agora/Stake/validator/set delegate/set delegate to something,168741237,431209,8343
|
||||||
Agora/Proposal/policy (proposal creation)/legal/proposal,30050955,75784,2649
|
Agora/Proposal/policy (proposal creation)/legal/proposal,33965500,89285,2794
|
||||||
Agora/Proposal/policy (proposal creation)/legal/governor,276624956,722480,12216
|
Agora/Proposal/policy (proposal creation)/legal/governor,286951289,757722,12319
|
||||||
Agora/Proposal/policy (proposal creation)/legal/stake,299062773,743108,8183
|
Agora/Proposal/policy (proposal creation)/legal/stake,300497720,755854,9135
|
||||||
Agora/Proposal/policy (proposal creation)/illegal/invalid next proposal id/proposal,30050955,75784,2649
|
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,299062773,743108,8183
|
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,30050955,75784,2617
|
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,276624956,722480,12185
|
Agora/Proposal/policy (proposal creation)/illegal/use other's stake/governor,286951289,757722,12288
|
||||||
Agora/Proposal/policy (proposal creation)/illegal/altered stake/proposal,30050955,75784,2649
|
Agora/Proposal/policy (proposal creation)/illegal/altered stake/proposal,33965500,89285,2794
|
||||||
Agora/Proposal/policy (proposal creation)/illegal/invalid stake locks/proposal,30050955,75784,2657
|
Agora/Proposal/policy (proposal creation)/illegal/invalid stake locks/proposal,33965500,89285,2809
|
||||||
Agora/Proposal/policy (proposal creation)/illegal/invalid stake locks/governor,276624956,722480,12224
|
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,30050955,75784,2669
|
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,311761209,779324,8213
|
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,30050955,75784,2649
|
Agora/Proposal/policy (proposal creation)/illegal/loose time range/proposal,33965500,89285,2794
|
||||||
Agora/Proposal/policy (proposal creation)/illegal/loose time range/stake,299062773,743108,8183
|
Agora/Proposal/policy (proposal creation)/illegal/loose time range/stake,300497720,755854,9135
|
||||||
Agora/Proposal/policy (proposal creation)/illegal/open time range/proposal,30050955,75784,2645
|
Agora/Proposal/policy (proposal creation)/illegal/open time range/proposal,33965500,89285,2790
|
||||||
Agora/Proposal/policy (proposal creation)/illegal/open time range/stake,299062773,743108,8179
|
Agora/Proposal/policy (proposal creation)/illegal/open time range/stake,300497720,755854,9131
|
||||||
Agora/Proposal/policy (proposal creation)/illegal/invalid proposal status/VotingReady/proposal,30050955,75784,2649
|
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,299062773,743108,8183
|
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,30050955,75784,2649
|
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,299062773,743108,8183
|
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,30050955,75784,2649
|
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,299062773,743108,8183
|
Agora/Proposal/policy (proposal creation)/illegal/invalid proposal status/Finished/stake,300497720,755854,9135
|
||||||
Agora/Proposal/validator/cosignature/legal/proposal,201848764,555553,11866
|
Agora/Proposal/policy (proposal creation)/illegal/fake SST/proposal,33965500,89285,2701
|
||||||
Agora/Proposal/validator/cosignature/legal/stake,256214245,661528,7982
|
Agora/Proposal/policy (proposal creation)/illegal/wrong governor redeemer/stake,300497720,755854,9135
|
||||||
Agora/Proposal/validator/cosignature/illegal/insufficient staked amount/stake,256214245,661528,7982
|
Agora/Proposal/policy (proposal creation)/illegal/wrong governor redeemer/stake,300497720,755854,9135
|
||||||
Agora/Proposal/validator/cosignature/illegal/proposal locks not updated/proposal,201848764,555553,11860
|
Agora/Proposal/validator/cosignature/legal/proposal,211218458,586864,12534
|
||||||
Agora/Proposal/validator/cosignature/illegal/duplicate cosigners/stake,262563463,679636,7999
|
Agora/Proposal/validator/cosignature/legal/stake,262516096,688466,8924
|
||||||
Agora/Proposal/validator/cosignature/illegal/cosigners not updated/stake,256214245,661528,7948
|
Agora/Proposal/validator/cosignature/illegal/insufficient staked amount/stake,262516096,688466,8924
|
||||||
Agora/Proposal/validator/cosignature/illegal/cosign after draft/(negative test)/stake,256214245,661528,7982
|
Agora/Proposal/validator/cosignature/illegal/proposal locks not updated/proposal,211218458,586864,12527
|
||||||
Agora/Proposal/validator/cosignature/illegal/cosign after draft/(negative test)/stake,256214245,661528,7982
|
Agora/Proposal/validator/cosignature/illegal/duplicate cosigners/stake,270695722,712030,8944
|
||||||
Agora/Proposal/validator/cosignature/illegal/cosign after draft/(negative test)/stake,256214245,661528,7982
|
Agora/Proposal/validator/cosignature/illegal/cosigners not updated/stake,262516096,688466,8890
|
||||||
Agora/Proposal/validator/voting/legal/different number of stakes/1 stakes/by owner/proposal,217201178,603628,11718
|
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/stake,270982879,701289,7845
|
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 delegatee/proposal,217201178,603628,11718
|
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 delegatee/stake,277809774,718445,7845
|
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/3 stakes/by owner/proposal,323914032,882782,12933
|
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/3 stakes/by owner/stake,561081905,1375723,9060
|
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/3 stakes/by delegatee/proposal,323914032,882782,12933
|
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 delegatee/stake,567908800,1392879,9060
|
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/5 stakes/by owner/proposal,430626886,1161936,14148
|
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/5 stakes/by owner/stake,851180931,2050157,10275
|
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/5 stakes/by delegatee/proposal,430626886,1161936,14148
|
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 delegatee/stake,858007826,2067313,10275
|
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/7 stakes/by owner/proposal,537339740,1441090,15362
|
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/7 stakes/by owner/stake,1141279957,2724591,11489
|
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/7 stakes/by delegatee/proposal,537339740,1441090,15362
|
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 delegatee/stake,1148106852,2741747,11489
|
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/9 stakes/by owner/proposal,644052594,1720244,16577
|
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/9 stakes/by owner/stake,1431378983,3399025,12704
|
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/9 stakes/by delegatee/proposal,644052594,1720244,16577
|
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 delegatee/stake,1438205878,3416181,12704
|
Agora/Proposal/validator/voting/legal/different number of stakes/9 stakes/by owner/proposal,721807619,1978876,17323
|
||||||
Agora/Proposal/validator/voting/legal/transparent non-GT tokens/proposal,217201178,603628,11718
|
Agora/Proposal/validator/voting/legal/different number of stakes/9 stakes/by owner/stake,1499207262,3654309,13729
|
||||||
Agora/Proposal/validator/voting/legal/transparent non-GT tokens/stake,270982879,701289,7845
|
Agora/Proposal/validator/voting/legal/different number of stakes/9 stakes/by delegatee/proposal,721807619,1978876,17323
|
||||||
Agora/Proposal/validator/voting/illegal/vote for nonexistent outcome/stake,270982879,701289,7850
|
Agora/Proposal/validator/voting/legal/different number of stakes/9 stakes/by delegatee/stake,1506034157,3671465,13729
|
||||||
Agora/Proposal/validator/voting/illegal/unauthorized tx/proposal,217201178,603628,11718
|
Agora/Proposal/validator/voting/legal/transparent non-GT tokens/proposal,236746075,667092,12391
|
||||||
Agora/Proposal/validator/voting/illegal/more than one proposals/stake,270982879,701289,7850
|
Agora/Proposal/validator/voting/legal/transparent non-GT tokens/stake,286719534,754693,8797
|
||||||
Agora/Proposal/validator/voting/illegal/locks not added/proposal,430626886,1161936,14118
|
Agora/Proposal/validator/voting/legal/Delegatee vote with own and delegated stakes in one tx/proposal,476847859,1315884,14788
|
||||||
Agora/Proposal/validator/voting/illegal/attempt to burn stakes/proposal,407560031,1110316,13089
|
Agora/Proposal/validator/voting/legal/Delegatee vote with own and delegated stakes in one tx/stake,902897522,2219654,11194
|
||||||
Agora/Proposal/validator/voting/illegal/insufficient staked amount/stake,270982879,701289,7822
|
Agora/Proposal/validator/voting/illegal/vote for nonexistent outcome/stake,286719534,754693,8805
|
||||||
Agora/Proposal/validator/voting/illegal/insufficient staked amount/stake,851180931,2050157,10187
|
Agora/Proposal/validator/voting/illegal/unauthorized tx/proposal,236746075,667092,12391
|
||||||
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/voting/illegal/more than one proposals/stake,286719534,754693,8805
|
||||||
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/voting/illegal/locks not added/proposal,479276847,1322984,14803
|
||||||
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/voting/illegal/attempt to burn stakes/proposal,441096352,1210784,13765
|
||||||
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/voting/illegal/insufficient staked amount/stake,286719534,754693,8792
|
||||||
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/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,237958208,660697,12053
|
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,217345310,603682,11816
|
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,230752943,630830,12908
|
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,401005973,1057563,12821
|
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,82449293,203081,3287
|
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 failed state/from Draft to Finished/proposal,212215847,594571,12088
|
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 failed state/from VotingReady to Finished/proposal,210487464,584281,12089
|
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 failed state/from Locked to Finished/proposal,222674368,615093,12089
|
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 failed state/from Draft to Finished/proposal,208404557,582343,11809
|
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 failed state/from VotingReady to Finished/proposal,206676174,572053,11810
|
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 Locked to Finished/proposal,218863078,602865,11810
|
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/illegal/advance finished proposals/(negative test)/authority,87514895,216737,3652
|
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/illegal/advance finished proposals/(negative test)/authority,82449293,203081,3287
|
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/illegal/to next state too late/from Locked/governor,403373267,1065069,13186
|
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/illegal/to next state too late/from Locked/authority,87514895,216737,3652
|
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/illegal/to next state too late/from Locked/governor,401005973,1057563,12821
|
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/to next state too late/from Locked/authority,82449293,203081,3287
|
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/forget to mint GATs/proposal,230752943,630830,12262
|
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/mint GATs for wrong validators/proposal,230752943,630830,12908
|
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/mint GATs for wrong validators/authority,82449293,203081,3287
|
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/mint GATs with bad token name/proposal,230752943,630830,12940
|
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/mint GATs with bad token name/authority,82449293,203081,3319
|
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/wrong GAT datum/proposal,230752943,630830,12902
|
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/wrong GAT datum/authority,82449293,203081,3281
|
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/invalid governor output datum/proposal,230752943,630830,12908
|
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/invalid governor output datum/authority,82449293,203081,3287
|
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 2 effects/legal/to next state/from Draft to VotingReady/proposal,315994218,877227,13248
|
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 2 effects/legal/to next state/from VotingReady to Locked/proposal,299076206,830200,13011
|
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 2 effects/legal/to next state/from Locked to Finished/proposal,308788953,847360,14282
|
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 2 effects/legal/to next state/from Locked to Finished/governor,445108495,1182301,13797
|
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 2 effects/legal/to next state/from Locked to Finished/authority,87514895,216737,4263
|
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 2 effects/legal/to next state/from Draft to VotingReady/proposal,308371638,852771,12687
|
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 VotingReady to Locked/proposal,291453626,805744,12450
|
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 Locked to Finished/proposal,301166373,822904,13543
|
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/governor,440986588,1168681,13245
|
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/authority,82449293,203081,3711
|
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 failed state/from Draft to Finished/proposal,286440567,798873,13004
|
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 failed state/from VotingReady to Finished/proposal,284712184,788583,13005
|
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 failed state/from Locked to Finished/proposal,296899088,819395,13005
|
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 failed state/from Draft to Finished/proposal,278817987,774417,12443
|
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 failed state/from VotingReady to Finished/proposal,277089604,764127,12444
|
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 failed state/from Locked to Finished/proposal,289276508,794939,12444
|
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/illegal/advance finished proposals/(negative test)/authority,87514895,216737,4263
|
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/illegal/advance finished proposals/(negative test)/authority,82449293,203081,3711
|
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/illegal/to next state too late/from Locked/governor,445108495,1182301,13797
|
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/illegal/to next state too late/from Locked/authority,87514895,216737,4263
|
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/illegal/to next state too late/from Locked/governor,440986588,1168681,13245
|
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/illegal/to next state too late/from Locked/authority,82449293,203081,3711
|
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/forget to mint GATs/proposal,301166373,822904,12897
|
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/mint GATs for wrong validators/proposal,301166373,822904,13543
|
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/mint GATs for wrong validators/authority,82449293,203081,3711
|
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/mint GATs with bad token name/proposal,301166373,822904,13575
|
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/mint GATs with bad token name/authority,82449293,203081,3743
|
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/wrong GAT datum/proposal,301166373,822904,13537
|
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/wrong GAT datum/authority,82449293,203081,3705
|
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/invalid governor output datum/proposal,301166373,822904,13543
|
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/invalid governor output datum/authority,82449293,203081,3711
|
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 5 effects/legal/to next state/from Draft to VotingReady/proposal,538668378,1490133,15995
|
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 5 effects/legal/to next state/from VotingReady to Locked/proposal,532835024,1473070,15758
|
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 5 effects/legal/to next state/from Locked to Finished/proposal,531463113,1460266,17029
|
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 5 effects/legal/to next state/from Locked to Finished/governor,570314179,1533997,15628
|
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 5 effects/legal/to next state/from Locked to Finished/authority,87514895,216737,6094
|
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 5 effects/legal/to next state/from Draft to VotingReady/proposal,519611928,1428993,14594
|
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 5 effects/legal/to next state/from VotingReady to Locked/proposal,513778574,1411930,14357
|
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 Locked to Finished/proposal,512406663,1399126,15450
|
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 Locked to Finished/governor,560928433,1502035,14516
|
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/authority,82449293,203081,4982
|
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 failed state/from Draft to Finished/proposal,509114727,1411779,15751
|
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 failed state/from VotingReady to Finished/proposal,507386344,1401489,15752
|
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 failed state/from Locked to Finished/proposal,519573248,1432301,15752
|
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 failed state/from Draft to Finished/proposal,490058277,1350639,14350
|
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 failed state/from VotingReady to Finished/proposal,488329894,1340349,14351
|
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 failed state/from Locked to Finished/proposal,500516798,1371161,14351
|
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/illegal/advance finished proposals/(negative test)/authority,87514895,216737,6094
|
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/illegal/advance finished proposals/(negative test)/authority,82449293,203081,4982
|
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/illegal/to next state too late/from Locked/governor,570314179,1533997,15628
|
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/illegal/to next state too late/from Locked/authority,87514895,216737,6094
|
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/illegal/to next state too late/from Locked/governor,560928433,1502035,14516
|
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/illegal/to next state too late/from Locked/authority,82449293,203081,4982
|
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/illegal/forget to mint GATs/proposal,512406663,1399126,14804
|
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/mint GATs for wrong validators/proposal,512406663,1399126,15450
|
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/mint GATs for wrong validators/authority,82449293,203081,4982
|
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/mint GATs with bad token name/proposal,512406663,1399126,15482
|
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/mint GATs with bad token name/authority,82449293,203081,5014
|
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/wrong GAT datum/proposal,512406663,1399126,15444
|
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/wrong GAT datum/authority,82449293,203081,4976
|
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/invalid governor output datum/proposal,512406663,1399126,15450
|
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/invalid governor output datum/authority,82449293,203081,4982
|
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 5 cosigners and 1 effects/legal/to next state/from Draft to VotingReady/proposal,421896692,1152021,13833
|
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 5 cosigners and 1 effects/legal/to next state/from VotingReady to Locked/proposal,251507320,699638,12506
|
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 5 cosigners and 1 effects/legal/to next state/from Locked to Finished/proposal,264914953,726786,13776
|
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 5 cosigners and 1 effects/legal/to next state/from Locked to Finished/governor,418246563,1106933,13459
|
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/wrong GAT datum/proposal,521175360,1427468,16176
|
||||||
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 1 cosigners and 5 effects/illegal/wrong GAT datum/authority,91691192,229170,5349
|
||||||
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 1 cosigners and 5 effects/illegal/invalid governor output datum/proposal,521175360,1427468,16182
|
||||||
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 1 cosigners and 5 effects/illegal/invalid governor output datum/authority,91691192,229170,5355
|
||||||
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 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 Locked to Finished/governor,415879269,1099427,13094
|
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 Locked to Finished/authority,82449293,203081,3560
|
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 failed state/from Draft to Finished/proposal,242566567,678299,12498
|
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 failed state/from VotingReady to Finished/proposal,240838184,668009,12499
|
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 failed state/from Locked to Finished/proposal,253025088,698821,12499
|
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 failed state/from Draft to Finished/proposal,238755277,666071,12218
|
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 failed state/from VotingReady to Finished/proposal,237026894,655781,12219
|
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 failed state/from Locked to Finished/proposal,249213798,686593,12219
|
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/illegal/advance finished proposals/(negative test)/authority,87514895,216737,3925
|
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/illegal/advance finished proposals/(negative test)/authority,82449293,203081,3560
|
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/illegal/to next state too late/from Locked/governor,418246563,1106933,13459
|
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/illegal/to next state too late/from Locked/authority,87514895,216737,3925
|
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/illegal/to next state too late/from Locked/governor,415879269,1099427,13094
|
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/illegal/to next state too late/from Locked/authority,82449293,203081,3560
|
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/illegal/forget to mint GATs/proposal,261103663,714558,12672
|
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/illegal/mint GATs for wrong validators/proposal,261103663,714558,13317
|
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/mint GATs for wrong validators/authority,82449293,203081,3560
|
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/mint GATs with bad token name/proposal,261103663,714558,13349
|
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/mint GATs with bad token name/authority,82449293,203081,3592
|
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/wrong GAT datum/proposal,261103663,714558,13311
|
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/wrong GAT datum/authority,82449293,203081,3554
|
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/invalid governor output datum/proposal,261103663,714558,13317
|
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/invalid governor output datum/authority,82449293,203081,3560
|
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 2 effects/legal/to next state/from Draft to VotingReady/proposal,496121412,1356323,14748
|
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 2 effects/legal/to next state/from VotingReady to Locked/proposal,329426926,913928,13421
|
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 2 effects/legal/to next state/from Locked to Finished/proposal,339139673,931088,14692
|
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 2 effects/legal/to next state/from Locked to Finished/governor,459981791,1224165,14070
|
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 2 effects/legal/to next state/from Locked to Finished/authority,87514895,216737,4536
|
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 2 effects/legal/to next state/from Draft to VotingReady/proposal,488498832,1331867,14188
|
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 2 effects/legal/to next state/from VotingReady to Locked/proposal,321804346,889472,12860
|
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 2 effects/legal/to next state/from Locked to Finished/proposal,331517093,906632,13953
|
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 2 effects/legal/to next state/from Locked to Finished/governor,455859884,1210545,13518
|
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 Locked to Finished/authority,82449293,203081,3984
|
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 failed state/from Draft to Finished/proposal,316791287,882601,13414
|
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 failed state/from VotingReady to Finished/proposal,315062904,872311,13415
|
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 failed state/from Locked to Finished/proposal,327249808,903123,13415
|
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 failed state/from Draft to Finished/proposal,309168707,858145,12853
|
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 failed state/from VotingReady to Finished/proposal,307440324,847855,12854
|
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 failed state/from Locked to Finished/proposal,319627228,878667,12854
|
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/illegal/advance finished proposals/(negative test)/authority,87514895,216737,4536
|
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/illegal/advance finished proposals/(negative test)/authority,82449293,203081,3984
|
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/illegal/to next state too late/from Locked/governor,459981791,1224165,14070
|
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/illegal/to next state too late/from Locked/authority,87514895,216737,4536
|
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/illegal/to next state too late/from Locked/governor,455859884,1210545,13518
|
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/illegal/to next state too late/from Locked/authority,82449293,203081,3984
|
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/illegal/forget to mint GATs/proposal,331517093,906632,13307
|
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/illegal/mint GATs for wrong validators/proposal,331517093,906632,13953
|
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/illegal/mint GATs for wrong validators/authority,82449293,203081,3984
|
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/mint GATs with bad token name/proposal,331517093,906632,13985
|
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/mint GATs with bad token name/authority,82449293,203081,4016
|
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/wrong GAT datum/proposal,331517093,906632,13947
|
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/wrong GAT datum/authority,82449293,203081,3978
|
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/invalid governor output datum/proposal,331517093,906632,13953
|
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/invalid governor output datum/authority,82449293,203081,3984
|
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 5 effects/legal/to next state/from Draft to VotingReady/proposal,718795572,1969229,17494
|
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 5 effects/legal/to next state/from VotingReady to Locked/proposal,563185744,1556798,16167
|
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 5 effects/legal/to next state/from Locked to Finished/proposal,561813833,1543994,17438
|
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 5 effects/legal/to next state/from Locked to Finished/governor,585187475,1575861,15901
|
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 5 effects/legal/to next state/from Locked to Finished/authority,87514895,216737,6367
|
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 5 effects/legal/to next state/from Draft to VotingReady/proposal,699739122,1908089,16094
|
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 5 effects/legal/to next state/from VotingReady to Locked/proposal,544129294,1495658,14766
|
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 5 effects/legal/to next state/from Locked to Finished/proposal,542757383,1482854,15859
|
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 5 effects/legal/to next state/from Locked to Finished/governor,575801729,1543899,14789
|
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 5 effects/legal/to next state/from Locked to Finished/authority,82449293,203081,5255
|
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 failed state/from Draft to Finished/proposal,539465447,1495507,16160
|
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 failed state/from VotingReady to Finished/proposal,537737064,1485217,16161
|
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 failed state/from Locked to Finished/proposal,549923968,1516029,16161
|
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 failed state/from Draft to Finished/proposal,520408997,1434367,14759
|
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 failed state/from VotingReady to Finished/proposal,518680614,1424077,14760
|
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 failed state/from Locked to Finished/proposal,530867518,1454889,14760
|
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/illegal/advance finished proposals/(negative test)/authority,87514895,216737,6367
|
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/illegal/advance finished proposals/(negative test)/authority,82449293,203081,5255
|
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/illegal/to next state too late/from Locked/governor,585187475,1575861,15901
|
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/illegal/to next state too late/from Locked/authority,87514895,216737,6367
|
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/illegal/to next state too late/from Locked/governor,575801729,1543899,14789
|
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/illegal/to next state too late/from Locked/authority,82449293,203081,5255
|
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/illegal/forget to mint GATs/proposal,542757383,1482854,15213
|
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/illegal/mint GATs for wrong validators/proposal,542757383,1482854,15859
|
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/illegal/mint GATs for wrong validators/authority,82449293,203081,5255
|
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/illegal/mint GATs with bad token name/proposal,542757383,1482854,15891
|
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/mint GATs with bad token name/authority,82449293,203081,5287
|
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/wrong GAT datum/proposal,542757383,1482854,15853
|
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/wrong GAT datum/authority,82449293,203081,5249
|
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/invalid governor output datum/proposal,542757383,1482854,15859
|
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/invalid governor output datum/authority,82449293,203081,5255
|
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 10 cosigners and 1 effects/legal/to next state/from Draft to VotingReady/proposal,662219128,1796582,15709
|
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 10 cosigners and 1 effects/legal/to next state/from VotingReady to Locked/proposal,289445720,804298,13017
|
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/forget to mint GATs/proposal,551526080,1511196,15946
|
||||||
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 5 cosigners and 5 effects/illegal/mint GATs for wrong validators/proposal,551526080,1511196,16592
|
||||||
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 5 cosigners and 5 effects/illegal/mint GATs for wrong validators/authority,91691192,229170,5628
|
||||||
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 5 cosigners and 5 effects/illegal/mint GATs with bad token name/proposal,551526080,1511196,16624
|
||||||
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 5 cosigners and 5 effects/illegal/mint GATs with bad token name/authority,91691192,229170,5660
|
||||||
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 5 cosigners and 5 effects/illegal/wrong GAT datum/proposal,551526080,1511196,16586
|
||||||
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 5 cosigners and 5 effects/illegal/wrong GAT datum/authority,91691192,229170,5622
|
||||||
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 5 cosigners and 5 effects/illegal/invalid governor output datum/proposal,551526080,1511196,16592
|
||||||
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 5 cosigners and 5 effects/illegal/invalid governor output datum/authority,91691192,229170,5628
|
||||||
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 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 failed state/from VotingReady to Finished/proposal,278776584,772669,13011
|
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 failed state/from Locked to Finished/proposal,290963488,803481,13011
|
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 failed state/from Draft to Finished/proposal,276693677,770731,12730
|
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 failed state/from VotingReady to Finished/proposal,274965294,760441,12731
|
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 failed state/from Locked to Finished/proposal,287152198,791253,12731
|
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/illegal/advance finished proposals/(negative test)/authority,87514895,216737,4267
|
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/illegal/advance finished proposals/(negative test)/authority,82449293,203081,3901
|
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/illegal/to next state too late/from Locked/governor,436838183,1159263,13801
|
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/illegal/to next state too late/from Locked/authority,87514895,216737,4267
|
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/illegal/to next state too late/from Locked/governor,434470889,1151757,13435
|
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/illegal/to next state too late/from Locked/authority,82449293,203081,3901
|
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/illegal/forget to mint GATs/proposal,299042063,819218,13184
|
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/illegal/mint GATs for wrong validators/proposal,299042063,819218,13829
|
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/illegal/mint GATs for wrong validators/authority,82449293,203081,3901
|
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/illegal/mint GATs with bad token name/proposal,299042063,819218,13862
|
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/illegal/mint GATs with bad token name/authority,82449293,203081,3933
|
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/wrong GAT datum/proposal,299042063,819218,13823
|
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/wrong GAT datum/authority,82449293,203081,3895
|
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/invalid governor output datum/proposal,299042063,819218,13829
|
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/invalid governor output datum/authority,82449293,203081,3901
|
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 2 effects/legal/to next state/from Draft to VotingReady/proposal,736443848,2000884,16625
|
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 2 effects/legal/to next state/from VotingReady to Locked/proposal,367365326,1018588,13932
|
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 2 effects/legal/to next state/from Locked to Finished/proposal,377078073,1035748,15203
|
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 2 effects/legal/to next state/from Locked to Finished/governor,478573411,1276495,14411
|
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 2 effects/legal/to next state/from Locked to Finished/authority,87514895,216737,4877
|
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 2 effects/legal/to next state/from Draft to VotingReady/proposal,728821268,1976428,16065
|
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 2 effects/legal/to next state/from VotingReady to Locked/proposal,359742746,994132,13373
|
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 2 effects/legal/to next state/from Locked to Finished/proposal,369455493,1011292,14465
|
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 2 effects/legal/to next state/from Locked to Finished/governor,474451504,1262875,13859
|
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 2 effects/legal/to next state/from Locked to Finished/authority,82449293,203081,4325
|
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 2 effects/legal/to failed state/from Draft to Finished/proposal,354729687,987261,13925
|
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 2 effects/legal/to failed state/from VotingReady to Finished/proposal,353001304,976971,13926
|
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 failed state/from Locked to Finished/proposal,365188208,1007783,13926
|
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 failed state/from Draft to Finished/proposal,347107107,962805,13366
|
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 failed state/from VotingReady to Finished/proposal,345378724,952515,13367
|
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 failed state/from Locked to Finished/proposal,357565628,983327,13367
|
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/illegal/advance finished proposals/(negative test)/authority,87514895,216737,4877
|
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/illegal/advance finished proposals/(negative test)/authority,82449293,203081,4325
|
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/illegal/to next state too late/from Locked/governor,478573411,1276495,14411
|
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/illegal/to next state too late/from Locked/authority,87514895,216737,4877
|
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/illegal/to next state too late/from Locked/governor,474451504,1262875,13859
|
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/illegal/to next state too late/from Locked/authority,82449293,203081,4325
|
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/illegal/forget to mint GATs/proposal,369455493,1011292,13820
|
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/illegal/mint GATs for wrong validators/proposal,369455493,1011292,14465
|
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/illegal/mint GATs for wrong validators/authority,82449293,203081,4325
|
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/illegal/mint GATs with bad token name/proposal,369455493,1011292,14497
|
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/illegal/mint GATs with bad token name/authority,82449293,203081,4357
|
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/illegal/wrong GAT datum/proposal,369455493,1011292,14459
|
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/wrong GAT datum/authority,82449293,203081,4319
|
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/invalid governor output datum/proposal,369455493,1011292,14465
|
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/invalid governor output datum/authority,82449293,203081,4325
|
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 5 effects/legal/to next state/from Draft to VotingReady/proposal,959118008,2613790,19372
|
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 5 effects/legal/to next state/from VotingReady to Locked/proposal,601124144,1661458,16679
|
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 5 effects/legal/to next state/from Locked to Finished/proposal,599752233,1648654,17950
|
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 5 effects/legal/to next state/from Locked to Finished/governor,603779095,1628191,16242
|
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 5 effects/legal/to next state/from Locked to Finished/authority,87514895,216737,6708
|
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 5 effects/legal/to next state/from Draft to VotingReady/proposal,940061558,2552650,17971
|
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 5 effects/legal/to next state/from VotingReady to Locked/proposal,582067694,1600318,15279
|
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 5 effects/legal/to next state/from Locked to Finished/proposal,580695783,1587514,16371
|
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 5 effects/legal/to next state/from Locked to Finished/governor,594393349,1596229,15130
|
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 5 effects/legal/to next state/from Locked to Finished/authority,82449293,203081,5596
|
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 5 effects/legal/to failed state/from Draft to Finished/proposal,577403847,1600167,16672
|
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 5 effects/legal/to failed state/from VotingReady to Finished/proposal,575675464,1589877,16673
|
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 5 effects/legal/to failed state/from Locked to Finished/proposal,587862368,1620689,16673
|
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 failed state/from Draft to Finished/proposal,558347397,1539027,15272
|
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 failed state/from VotingReady to Finished/proposal,556619014,1528737,15273
|
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 failed state/from Locked to Finished/proposal,568805918,1559549,15273
|
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/illegal/advance finished proposals/(negative test)/authority,87514895,216737,6708
|
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/illegal/advance finished proposals/(negative test)/authority,82449293,203081,5596
|
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/illegal/to next state too late/from Locked/governor,603779095,1628191,16242
|
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/illegal/to next state too late/from Locked/authority,87514895,216737,6708
|
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/illegal/to next state too late/from Locked/governor,594393349,1596229,15130
|
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/illegal/to next state too late/from Locked/authority,82449293,203081,5596
|
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/illegal/forget to mint GATs/proposal,580695783,1587514,15725
|
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/illegal/mint GATs for wrong validators/proposal,580695783,1587514,16371
|
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/illegal/mint GATs for wrong validators/authority,82449293,203081,5596
|
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/illegal/mint GATs with bad token name/proposal,580695783,1587514,16403
|
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/illegal/mint GATs with bad token name/authority,82449293,203081,5628
|
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/illegal/wrong GAT datum/proposal,580695783,1587514,16365
|
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/illegal/wrong GAT datum/authority,82449293,203081,5590
|
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/invalid governor output datum/proposal,580695783,1587514,16371
|
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/invalid governor output datum/authority,82449293,203081,5596
|
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/advance finished proposals/(negative test)/authority,91691192,229170,5969
|
||||||
Agora/Proposal/validator/unlocking/legal/with 1 stakes/voter: retract votes while voting/stake,279058825,705875,8067
|
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/unlocking/legal/with 1 stakes/voter: retract votes while voting/proposal,216327247,595640,11945
|
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/unlocking/legal/with 1 stakes/voter: retract votes while voting by delegatee/stake,285885720,723031,8067
|
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/unlocking/legal/with 1 stakes/voter: retract votes while voting by delegatee/proposal,216327247,595640,11945
|
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/unlocking/legal/with 1 stakes/voter/creator: retract votes while voting/stake,289565080,736477,8083
|
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/forget to mint GATs/proposal,589464480,1615856,16458
|
||||||
Agora/Proposal/validator/unlocking/legal/with 1 stakes/voter/creator: retract votes while voting/proposal,222662651,614054,11956
|
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/mint GATs for wrong validators/proposal,589464480,1615856,17103
|
||||||
Agora/Proposal/validator/unlocking/legal/with 1 stakes/creator: remove creator lock after voting/stake,280060082,709082,8070
|
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/mint GATs for wrong validators/authority,91691192,229170,5969
|
||||||
Agora/Proposal/validator/unlocking/legal/with 1 stakes/creator: remove creator lock after voting/proposal,184227955,507972,11949
|
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/mint GATs with bad token name/proposal,589464480,1615856,17135
|
||||||
Agora/Proposal/validator/unlocking/legal/with 1 stakes/Voter: remove lock after voting/stake,280189803,708279,8072
|
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/mint GATs with bad token name/authority,91691192,229170,6001
|
||||||
Agora/Proposal/validator/unlocking/legal/with 1 stakes/Voter: remove lock after voting/proposal,185266232,510770,11950
|
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/wrong GAT datum/proposal,589464480,1615856,17097
|
||||||
Agora/Proposal/validator/unlocking/legal/with 3 stakes/voter: retract votes while voting/stake,577605005,1368019,9412
|
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/wrong GAT datum/authority,91691192,229170,5963
|
||||||
Agora/Proposal/validator/unlocking/legal/with 3 stakes/voter: retract votes while voting/proposal,327560147,886154,13290
|
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/invalid governor output datum/proposal,589464480,1615856,17103
|
||||||
Agora/Proposal/validator/unlocking/legal/with 3 stakes/voter: retract votes while voting by delegatee/stake,584431900,1385175,9412
|
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/invalid governor output datum/authority,91691192,229170,5969
|
||||||
Agora/Proposal/validator/unlocking/legal/with 3 stakes/voter: retract votes while voting by delegatee/proposal,327560147,886154,13290
|
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/wrong governor redeemer/proposal,589464480,1615856,17103
|
||||||
Agora/Proposal/validator/unlocking/legal/with 3 stakes/voter/creator: retract votes while voting/stake,609123770,1459825,9450
|
Agora/Proposal/validator/unlocking/legal/with 1 stakes/voter: retract votes while voting/stake,293224159,762702,9027
|
||||||
Agora/Proposal/validator/unlocking/legal/with 3 stakes/voter/creator: retract votes while voting/proposal,346566359,941396,13323
|
Agora/Proposal/validator/unlocking/legal/with 1 stakes/voter: retract votes while voting/proposal,250729998,700174,12627
|
||||||
Agora/Proposal/validator/unlocking/legal/with 3 stakes/creator: remove creator lock after voting/stake,578346820,1372832,9413
|
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 3 stakes/creator: remove creator lock after voting/proposal,251935769,673222,13292
|
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 3 stakes/Voter: remove lock after voting/stake,578735983,1370423,9417
|
Agora/Proposal/validator/unlocking/legal/with 1 stakes/voter/creator: retract votes while voting/stake,305673493,792301,9039
|
||||||
Agora/Proposal/validator/unlocking/legal/with 3 stakes/Voter: remove lock after voting/proposal,255050600,681616,13295
|
Agora/Proposal/validator/unlocking/legal/with 1 stakes/voter/creator: retract votes while voting/proposal,261958222,733268,12633
|
||||||
Agora/Proposal/validator/unlocking/legal/with 5 stakes/voter: retract votes while voting/stake,895797841,2061603,10758
|
Agora/Proposal/validator/unlocking/legal/with 1 stakes/creator: remove creator lock after voting/stake,286343529,742697,9020
|
||||||
Agora/Proposal/validator/unlocking/legal/with 5 stakes/voter: retract votes while voting/proposal,438793047,1176668,14636
|
Agora/Proposal/validator/unlocking/legal/with 1 stakes/creator: remove creator lock after voting/proposal,194627614,541712,12624
|
||||||
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 1 stakes/Voter: remove lock after voting/stake,290948981,754990,9032
|
||||||
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 1 stakes/Voter: remove lock after voting/proposal,196700632,547308,12632
|
||||||
Agora/Proposal/validator/unlocking/legal/with 5 stakes/voter/creator: retract votes while voting/stake,948329116,2214613,10818
|
Agora/Proposal/validator/unlocking/legal/with 3 stakes/voter: retract votes while voting/stake,582113987,1442022,10403
|
||||||
Agora/Proposal/validator/unlocking/legal/with 5 stakes/voter/creator: retract votes while voting/proposal,470470067,1268738,14691
|
Agora/Proposal/validator/unlocking/legal/with 3 stakes/voter: retract votes while voting/proposal,404537296,1122004,14003
|
||||||
Agora/Proposal/validator/unlocking/legal/with 5 stakes/creator: remove creator lock after voting/stake,896280214,2068022,10757
|
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 5 stakes/creator: remove creator lock after voting/proposal,319643583,838472,14636
|
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 5 stakes/Voter: remove lock after voting/stake,896928819,2064007,10763
|
Agora/Proposal/validator/unlocking/legal/with 3 stakes/voter/creator: retract votes while voting/stake,634196981,1554399,10427
|
||||||
Agora/Proposal/validator/unlocking/legal/with 5 stakes/Voter: remove lock after voting/proposal,324834968,852462,14641
|
Agora/Proposal/validator/unlocking/legal/with 3 stakes/voter/creator: retract votes while voting/proposal,438221968,1221286,14021
|
||||||
Agora/Proposal/validator/unlocking/legal/with 7 stakes/voter: retract votes while voting/stake,1233637333,2786627,12103
|
Agora/Proposal/validator/unlocking/legal/with 3 stakes/creator: remove creator lock after voting/stake,562666017,1388031,10379
|
||||||
Agora/Proposal/validator/unlocking/legal/with 7 stakes/voter: retract votes while voting/proposal,550025947,1467182,15981
|
Agora/Proposal/validator/unlocking/legal/with 3 stakes/creator: remove creator lock after voting/proposal,264253492,713018,13983
|
||||||
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 3 stakes/Voter: remove lock after voting/stake,576482373,1424910,10408
|
||||||
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 3 stakes/Voter: remove lock after voting/proposal,270472546,729806,14008
|
||||||
Agora/Proposal/validator/unlocking/legal/with 7 stakes/voter/creator: retract votes while voting/stake,1307181118,3000841,12185
|
Agora/Proposal/validator/unlocking/legal/with 5 stakes/voter: retract votes while voting/stake,871003815,2121342,11778
|
||||||
Agora/Proposal/validator/unlocking/legal/with 7 stakes/voter/creator: retract votes while voting/proposal,594373775,1596080,16058
|
Agora/Proposal/validator/unlocking/legal/with 5 stakes/voter: retract votes while voting/proposal,558344594,1543834,15378
|
||||||
Agora/Proposal/validator/unlocking/legal/with 7 stakes/creator: remove creator lock after voting/stake,1233860264,2794652,12100
|
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 7 stakes/creator: remove creator lock after voting/proposal,387351397,1003722,15979
|
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 7 stakes/Voter: remove lock after voting/stake,1234768311,2789031,12108
|
Agora/Proposal/validator/unlocking/legal/with 5 stakes/voter/creator: retract votes while voting/stake,982367125,2347937,11814
|
||||||
Agora/Proposal/validator/unlocking/legal/with 7 stakes/Voter: remove lock after voting/proposal,394619336,1023308,15986
|
Agora/Proposal/validator/unlocking/legal/with 5 stakes/voter/creator: retract votes while voting/proposal,614485714,1709304,15408
|
||||||
Agora/Proposal/validator/unlocking/legal/with 9 stakes/voter: retract votes while voting/stake,1591123481,3543091,13448
|
Agora/Proposal/validator/unlocking/legal/with 5 stakes/creator: remove creator lock after voting/stake,838988505,2033365,11739
|
||||||
Agora/Proposal/validator/unlocking/legal/with 9 stakes/voter: retract votes while voting/proposal,661258847,1757696,17326
|
Agora/Proposal/validator/unlocking/legal/with 5 stakes/creator: remove creator lock after voting/proposal,333879370,884324,15343
|
||||||
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 5 stakes/Voter: remove lock after voting/stake,862015765,2094830,11783
|
||||||
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 5 stakes/Voter: remove lock after voting/proposal,344244460,912304,15383
|
||||||
Agora/Proposal/validator/unlocking/legal/with 9 stakes/voter/creator: retract votes while voting/stake,1685679776,3818509,13552
|
Agora/Proposal/validator/unlocking/legal/with 7 stakes/voter: retract votes while voting/stake,1159893643,2800662,13153
|
||||||
Agora/Proposal/validator/unlocking/legal/with 9 stakes/voter/creator: retract votes while voting/proposal,718277483,1923422,17425
|
Agora/Proposal/validator/unlocking/legal/with 7 stakes/voter: retract votes while voting/proposal,712151892,1965664,16753
|
||||||
Agora/Proposal/validator/unlocking/legal/with 9 stakes/creator: remove creator lock after voting/stake,1591086970,3552722,13443
|
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 9 stakes/creator: remove creator lock after voting/proposal,455059211,1168972,17322
|
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 9 stakes/Voter: remove lock after voting/stake,1592254459,3545495,13453
|
Agora/Proposal/validator/unlocking/legal/with 7 stakes/voter/creator: retract votes while voting/stake,1350183925,3172915,13201
|
||||||
Agora/Proposal/validator/unlocking/legal/with 9 stakes/Voter: remove lock after voting/proposal,464403704,1194154,17331
|
Agora/Proposal/validator/unlocking/legal/with 7 stakes/voter/creator: retract votes while voting/proposal,790749460,2197322,16795
|
||||||
Agora/Proposal/validator/unlocking/legal/with 11 stakes/voter: retract votes while voting/stake,1968256285,4330995,14794
|
Agora/Proposal/validator/unlocking/legal/with 7 stakes/creator: remove creator lock after voting/stake,1115310993,2678699,13098
|
||||||
Agora/Proposal/validator/unlocking/legal/with 11 stakes/voter: retract votes while voting/proposal,772491747,2048210,18672
|
Agora/Proposal/validator/unlocking/legal/with 7 stakes/creator: remove creator lock after voting/proposal,403505248,1055630,16702
|
||||||
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 7 stakes/Voter: remove lock after voting/stake,1147549157,2764750,13158
|
||||||
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 7 stakes/Voter: remove lock after voting/proposal,418016374,1094802,16758
|
||||||
Agora/Proposal/validator/unlocking/legal/with 11 stakes/voter/creator: retract votes while voting/stake,2083825090,4667617,14921
|
Agora/Proposal/validator/unlocking/legal/with 9 stakes/voter: retract votes while voting/stake,1448783471,3479982,14529
|
||||||
Agora/Proposal/validator/unlocking/legal/with 11 stakes/voter/creator: retract votes while voting/proposal,842181191,2250764,18794
|
Agora/Proposal/validator/unlocking/legal/with 9 stakes/voter: retract votes while voting/proposal,865959190,2387494,18129
|
||||||
Agora/Proposal/validator/unlocking/legal/with 11 stakes/creator: remove creator lock after voting/stake,1967960332,4342232,14787
|
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 11 stakes/creator: remove creator lock after voting/proposal,522767025,1334222,18666
|
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 11 stakes/Voter: remove lock after voting/stake,1969387263,4333399,14799
|
Agora/Proposal/validator/unlocking/legal/with 9 stakes/voter/creator: retract votes while voting/stake,1737647381,4029333,14589
|
||||||
Agora/Proposal/validator/unlocking/legal/with 11 stakes/Voter: remove lock after voting/proposal,534188072,1365000,18677
|
Agora/Proposal/validator/unlocking/legal/with 9 stakes/voter/creator: retract votes while voting/proposal,967013206,2685340,18183
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 1 stakes/retract votes while not voting/(negative test)/stake,278493336,704673,8067
|
Agora/Proposal/validator/unlocking/legal/with 9 stakes/creator: remove creator lock after voting/stake,1391633481,3324033,14457
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 1 stakes/retract votes while not voting/(negative test)/stake,279624314,707077,8067
|
Agora/Proposal/validator/unlocking/legal/with 9 stakes/creator: remove creator lock after voting/proposal,473131126,1226936,18061
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 1 stakes/retract votes while not voting/(negative test)/stake,280189803,708279,8067
|
Agora/Proposal/validator/unlocking/legal/with 9 stakes/Voter: remove lock after voting/stake,1433082549,3434670,14534
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 1 stakes/remove creator too early/(negative test)/proposal,182531488,504366,11949
|
Agora/Proposal/validator/unlocking/legal/with 9 stakes/Voter: remove lock after voting/proposal,491788288,1277300,18134
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 1 stakes/remove creator too early/(negative test)/proposal,190464307,523106,11949
|
Agora/Proposal/validator/unlocking/legal/with 11 stakes/voter: retract votes while voting/stake,1737673299,4159302,15905
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 1 stakes/remove creator too early/(negative test)/proposal,183662466,506770,11949
|
Agora/Proposal/validator/unlocking/legal/with 11 stakes/voter: retract votes while voting/proposal,1019766488,2809324,19505
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 1 stakes/unlock an irrelevant stake/stake,288706362,739001,8089
|
Agora/Proposal/validator/unlocking/legal/with 11 stakes/voter: retract votes while voting by delegatee/stake,1744500194,4176458,15905
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 1 stakes/creator: retract votes/stake,277406179,708304,8071
|
Agora/Proposal/validator/unlocking/legal/with 11 stakes/voter: retract votes while voting by delegatee/proposal,1019766488,2809324,19505
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 1 stakes/change output stake value/proposal,216327247,595640,11942
|
Agora/Proposal/validator/unlocking/legal/with 11 stakes/voter/creator: retract votes while voting/stake,2144757493,4917191,15977
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 3 stakes/retract votes while not voting/(negative test)/stake,577039516,1366817,9412
|
Agora/Proposal/validator/unlocking/legal/with 11 stakes/voter/creator: retract votes while voting/proposal,1143276952,3173358,19571
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 3 stakes/retract votes while not voting/(negative test)/stake,578170494,1369221,9412
|
Agora/Proposal/validator/unlocking/legal/with 11 stakes/creator: remove creator lock after voting/stake,1667955969,3969367,15818
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 3 stakes/retract votes while not voting/(negative test)/stake,578735983,1370423,9412
|
Agora/Proposal/validator/unlocking/legal/with 11 stakes/creator: remove creator lock after voting/proposal,542757004,1398242,19422
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 3 stakes/remove creator too early/(negative test)/proposal,250239302,669616,13292
|
Agora/Proposal/validator/unlocking/legal/with 11 stakes/Voter: remove lock after voting/stake,1718615941,4104590,15910
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 3 stakes/remove creator too early/(negative test)/proposal,258172121,688356,13292
|
Agora/Proposal/validator/unlocking/legal/with 11 stakes/Voter: remove lock after voting/proposal,565560202,1459798,19510
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 3 stakes/remove creator too early/(negative test)/proposal,251370280,672020,13292
|
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 3 stakes/unlock an irrelevant stake/stake,591812624,1443817,9468
|
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 3 stakes/creator: retract votes/stake,557912075,1351726,9426
|
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 3 stakes/change output stake value/proposal,327560147,886154,13281
|
Agora/Proposal/validator/unlocking/illegal/with 1 stakes/remove creator too early/(negative test)/proposal,192931147,538106,12624
|
||||||
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 1 stakes/remove creator too early/(negative test)/proposal,201089148,557678,12624
|
||||||
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 1 stakes/remove creator too early/(negative test)/proposal,194062125,540510,12624
|
||||||
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 1 stakes/unlock an irrelevant stake/stake,294561760,762166,9028
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 5 stakes/remove creator too early/(negative test)/proposal,317947116,834866,14636
|
Agora/Proposal/validator/unlocking/illegal/with 1 stakes/creator: retract votes/stake,287523038,741355,9008
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 5 stakes/remove creator too early/(negative test)/proposal,325879935,853606,14636
|
Agora/Proposal/validator/unlocking/illegal/with 1 stakes/change output stake value/proposal,250729998,700174,12624
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 5 stakes/remove creator too early/(negative test)/proposal,319078094,837270,14636
|
Agora/Proposal/validator/unlocking/illegal/with 1 stakes/retract votes in cooldown/proposal,261958222,733268,12633
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 5 stakes/unlock an irrelevant stake/stake,894918886,2148633,10848
|
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 5 stakes/creator: retract votes/stake,838417971,1995148,10782
|
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 5 stakes/change output stake value/proposal,438793047,1176668,14621
|
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 7 stakes/retract votes while not voting/(negative test)/stake,1233071844,2785425,12103
|
Agora/Proposal/validator/unlocking/illegal/with 3 stakes/remove creator too early/(negative test)/proposal,262557025,709412,13983
|
||||||
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 3 stakes/remove creator too early/(negative test)/proposal,270715026,728984,13983
|
||||||
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 3 stakes/remove creator too early/(negative test)/proposal,263688003,711816,13983
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 7 stakes/remove creator too early/(negative test)/proposal,385654930,1000116,15979
|
Agora/Proposal/validator/unlocking/illegal/with 3 stakes/unlock an irrelevant stake/stake,600861782,1463994,10393
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 7 stakes/remove creator too early/(negative test)/proposal,393587749,1018856,15979
|
Agora/Proposal/validator/unlocking/illegal/with 3 stakes/creator: retract votes/stake,579745616,1401561,10353
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 7 stakes/remove creator too early/(negative test)/proposal,386785908,1002520,15979
|
Agora/Proposal/validator/unlocking/illegal/with 3 stakes/change output stake value/proposal,404537296,1122004,13993
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 7 stakes/unlock an irrelevant stake/stake,1198025148,2853449,12227
|
Agora/Proposal/validator/unlocking/illegal/with 3 stakes/retract votes in cooldown/proposal,438221968,1221286,14021
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 7 stakes/creator: retract votes/stake,1118923867,2638570,12137
|
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 7 stakes/change output stake value/proposal,550025947,1467182,15960
|
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 9 stakes/retract votes while not voting/(negative test)/stake,1590557992,3541889,13448
|
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 9 stakes/retract votes while not voting/(negative test)/stake,1591688970,3544293,13448
|
Agora/Proposal/validator/unlocking/illegal/with 5 stakes/remove creator too early/(negative test)/proposal,332182903,880718,15343
|
||||||
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 5 stakes/remove creator too early/(negative test)/proposal,340340904,900290,15343
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 9 stakes/remove creator too early/(negative test)/proposal,453362744,1165366,17322
|
Agora/Proposal/validator/unlocking/illegal/with 5 stakes/remove creator too early/(negative test)/proposal,333313881,883122,15343
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 9 stakes/remove creator too early/(negative test)/proposal,461295563,1184106,17322
|
Agora/Proposal/validator/unlocking/illegal/with 5 stakes/unlock an irrelevant stake/stake,926808460,2197262,11759
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 9 stakes/remove creator too early/(negative test)/proposal,454493722,1167770,17322
|
Agora/Proposal/validator/unlocking/illegal/with 5 stakes/creator: retract votes/stake,891614850,2093207,11699
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 9 stakes/unlock an irrelevant stake/stake,1501131410,3558265,13607
|
Agora/Proposal/validator/unlocking/illegal/with 5 stakes/change output stake value/proposal,558344594,1543834,15363
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 9 stakes/creator: retract votes/stake,1399429763,3281992,13492
|
Agora/Proposal/validator/unlocking/illegal/with 5 stakes/retract votes in cooldown/proposal,614485714,1709304,15408
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 9 stakes/change output stake value/proposal,661258847,1757696,17299
|
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 11 stakes/retract votes while not voting/(negative test)/stake,1967690796,4329793,14794
|
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 11 stakes/retract votes while not voting/(negative test)/stake,1968821774,4332197,14794
|
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 11 stakes/retract votes while not voting/(negative test)/stake,1969387263,4333399,14794
|
Agora/Proposal/validator/unlocking/illegal/with 7 stakes/remove creator too early/(negative test)/proposal,401808781,1052024,16702
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 11 stakes/remove creator too early/(negative test)/proposal,521070558,1330616,18666
|
Agora/Proposal/validator/unlocking/illegal/with 7 stakes/remove creator too early/(negative test)/proposal,409966782,1071596,16702
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 11 stakes/remove creator too early/(negative test)/proposal,529003377,1349356,18666
|
Agora/Proposal/validator/unlocking/illegal/with 7 stakes/remove creator too early/(negative test)/proposal,402939759,1054428,16702
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 11 stakes/remove creator too early/(negative test)/proposal,522201536,1333020,18666
|
Agora/Proposal/validator/unlocking/illegal/with 7 stakes/unlock an irrelevant stake/stake,1272401794,2961970,13124
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 11 stakes/unlock an irrelevant stake/stake,1804237672,4263081,14987
|
Agora/Proposal/validator/unlocking/illegal/with 7 stakes/creator: retract votes/stake,1223130740,2816293,13044
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 11 stakes/creator: retract votes/stake,1679935659,3925414,14849
|
Agora/Proposal/validator/unlocking/illegal/with 7 stakes/change output stake value/proposal,712151892,1965664,16732
|
||||||
Agora/Proposal/validator/unlocking/illegal/with 11 stakes/change output stake value/proposal,772491747,2048210,18639
|
Agora/Proposal/validator/unlocking/illegal/with 7 stakes/retract votes in cooldown/proposal,790749460,2197322,16795
|
||||||
Agora/AuthorityToken/singleAuthorityTokenBurned/Correct simple,26456223,75851,755
|
Agora/Proposal/validator/unlocking/illegal/with 9 stakes/retract votes while not voting/(negative test)/stake,1448217982,3478780,14529
|
||||||
Agora/AuthorityToken/singleAuthorityTokenBurned/Correct many inputs,51581175,146321,855
|
Agora/Proposal/validator/unlocking/illegal/with 9 stakes/retract votes while not voting/(negative test)/stake,1449348960,3481184,14529
|
||||||
Agora/AuthorityToken/singleAuthorityTokenBurned/Correct even though scripts don't match,26456223,75851,754
|
Agora/Proposal/validator/unlocking/illegal/with 9 stakes/retract votes while not voting/(negative test)/stake,1433082549,3434670,14529
|
||||||
Agora/Treasury/Validator/Positive/Allows for effect changes,42170246,119764,1444
|
Agora/Proposal/validator/unlocking/illegal/with 9 stakes/remove creator too early/(negative test)/proposal,471434659,1223330,18061
|
||||||
Agora/Treasury/Validator/Positive/Fails when GAT token name is not script address,42170246,119764,1480
|
Agora/Proposal/validator/unlocking/illegal/with 9 stakes/remove creator too early/(negative test)/proposal,479592660,1242902,18061
|
||||||
Agora/AuthorityToken/singleAuthorityTokenBurned/Correct simple,26456223,75851,755
|
Agora/Proposal/validator/unlocking/illegal/with 9 stakes/remove creator too early/(negative test)/proposal,472565637,1225734,18061
|
||||||
Agora/AuthorityToken/singleAuthorityTokenBurned/Correct many inputs,51581175,146321,855
|
Agora/Proposal/validator/unlocking/illegal/with 9 stakes/unlock an irrelevant stake/stake,1637641784,3758118,14489
|
||||||
Agora/AuthorityToken/singleAuthorityTokenBurned/Correct even though scripts don't match,26456223,75851,754
|
Agora/Proposal/validator/unlocking/illegal/with 9 stakes/creator: retract votes/stake,1574293286,3570819,14389
|
||||||
Agora/Governor/policy/totally legal,63319800,170930,2766
|
Agora/Proposal/validator/unlocking/illegal/with 9 stakes/change output stake value/proposal,865959190,2387494,18102
|
||||||
Agora/Governor/validator/mutate/legal,129085947,358459,11531
|
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
|
||||||
|
|
|
||||||
|
62
flake.lock
generated
62
flake.lock
generated
|
|
@ -559,11 +559,11 @@
|
||||||
"nixpkgs-2205": "nixpkgs-2205"
|
"nixpkgs-2205": "nixpkgs-2205"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1660580223,
|
"lastModified": 1666695559,
|
||||||
"narHash": "sha256-r1i92rrUjSBdnQZpHLxeCAtVGMHYqKQHm05mzddIte8=",
|
"narHash": "sha256-v8DcNma4hAgLCbPHpsxNYzeMURfbxh20VXfFzUED6bs=",
|
||||||
"owner": "Liqwid-Labs",
|
"owner": "Liqwid-Labs",
|
||||||
"repo": "liqwid-nix",
|
"repo": "liqwid-nix",
|
||||||
"rev": "fa1eeba35b37ac2551a00798dffdf053879699c3",
|
"rev": "7add1f24e9360e96b2bab4a1fc7929d4fa649439",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -631,14 +631,15 @@
|
||||||
},
|
},
|
||||||
"liqwid-nix_6": {
|
"liqwid-nix_6": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": "nixpkgs_9"
|
"nixpkgs": "nixpkgs_9",
|
||||||
|
"nixpkgs-2205": "nixpkgs-2205_5"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1659383708,
|
"lastModified": 1666695559,
|
||||||
"narHash": "sha256-eenTO5t4ocK7VzorMUdUyKUoup976cCu5dJcVjebY8E=",
|
"narHash": "sha256-v8DcNma4hAgLCbPHpsxNYzeMURfbxh20VXfFzUED6bs=",
|
||||||
"owner": "Liqwid-Labs",
|
"owner": "Liqwid-Labs",
|
||||||
"repo": "liqwid-nix",
|
"repo": "liqwid-nix",
|
||||||
"rev": "c261df76dc31b3dc5dfde7030420e0a6be73f615",
|
"rev": "7add1f24e9360e96b2bab4a1fc7929d4fa649439",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -691,11 +692,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1666735011,
|
"lastModified": 1668121695,
|
||||||
"narHash": "sha256-ugpT7IHlga+fq8+CTYW+MZa4OT4f6Xp+UaWSbbJUTgM=",
|
"narHash": "sha256-2ltW7mvn14zm9f67OmxXIPJHAXR6vxBdN/6Q6nRh7a8=",
|
||||||
"owner": "Liqwid-Labs",
|
"owner": "Liqwid-Labs",
|
||||||
"repo": "liqwid-plutarch-extra",
|
"repo": "liqwid-plutarch-extra",
|
||||||
"rev": "a5be78478418aff2312787860f4736837f24494e",
|
"rev": "0cb63aa7d4fd2006cf590edc7fca0f3fcdb71a55",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -952,6 +953,38 @@
|
||||||
"type": "github"
|
"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": {
|
"nixpkgs-latest": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1666809571,
|
"lastModified": 1666809571,
|
||||||
|
|
@ -1311,6 +1344,7 @@
|
||||||
"nixpkgs-2111": [
|
"nixpkgs-2111": [
|
||||||
"nixpkgs-2111"
|
"nixpkgs-2111"
|
||||||
],
|
],
|
||||||
|
"nixpkgs-2205": "nixpkgs-2205_6",
|
||||||
"nixpkgs-latest": [
|
"nixpkgs-latest": [
|
||||||
"nixpkgs-latest"
|
"nixpkgs-latest"
|
||||||
],
|
],
|
||||||
|
|
@ -1319,16 +1353,16 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1659450065,
|
"lastModified": 1667344793,
|
||||||
"narHash": "sha256-x6B9sjrZaTite4TSLLyOWfmG3JJbOZuGUNMDZ1f4qhk=",
|
"narHash": "sha256-xbnqP7DL3rkjslh7wUGghiAv9ksbEebMih31YY/5nxg=",
|
||||||
"owner": "liqwid-labs",
|
"owner": "liqwid-labs",
|
||||||
"repo": "plutarch-quickcheck",
|
"repo": "plutarch-quickcheck",
|
||||||
"rev": "2c5b77f1a622ce68d80a09b286eb0ac85527ff26",
|
"rev": "4d369eccd35193ce723587d12c4eb2dfa21a824e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "liqwid-labs",
|
"owner": "liqwid-labs",
|
||||||
"ref": "staging",
|
"ref": "main",
|
||||||
"repo": "plutarch-quickcheck",
|
"repo": "plutarch-quickcheck",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@
|
||||||
inputs.ply.follows = "ply";
|
inputs.ply.follows = "ply";
|
||||||
};
|
};
|
||||||
plutarch-quickcheck = {
|
plutarch-quickcheck = {
|
||||||
url = "github:liqwid-labs/plutarch-quickcheck?ref=staging";
|
url = "github:liqwid-labs/plutarch-quickcheck?ref=main";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
inputs.nixpkgs-latest.follows = "nixpkgs-latest";
|
inputs.nixpkgs-latest.follows = "nixpkgs-latest";
|
||||||
inputs.nixpkgs-2111.follows = "nixpkgs-2111";
|
inputs.nixpkgs-2111.follows = "nixpkgs-2111";
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue