Merge pull request #186 from Liqwid-Labs/connor/vote-with-multiple-stakes
Voting with multiple stakes
This commit is contained in:
commit
4b9943f995
23 changed files with 2376 additions and 1892 deletions
|
|
@ -6,6 +6,13 @@ This format is based on [Keep A Changelog](https://keepachangelog.com/en/1.0.0).
|
|||
|
||||
### Modified
|
||||
|
||||
- Support voting/retracting votes with multiple stakes.
|
||||
|
||||
NOTE: Due to the fact that the order of stake locks is undefined, voting to
|
||||
multiple proposals in a single tx is disallowed.
|
||||
|
||||
Included by [#186](https://github.com/Liqwid-Labs/agora/pull/186)
|
||||
|
||||
- Fix a bug that allows an attacker to send two or more GATs to an effect in the winning effect group.
|
||||
|
||||
Fixed by [#181](https://github.com/Liqwid-Labs/agora/pull/181)
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ import Test.Tasty.QuickCheck (
|
|||
data GovernorDatumCases
|
||||
= ExecuteLE0
|
||||
| CreateLE0
|
||||
| ToVotingLE0
|
||||
| VoteLE0
|
||||
| Correct
|
||||
deriving stock (Eq, Show)
|
||||
|
|
@ -88,9 +89,10 @@ governorDatumValidProperty =
|
|||
classifiedPropertyNative gen (const []) expected classifier pisGovernorDatumValid
|
||||
where
|
||||
classifier :: GovernorDatum -> GovernorDatumCases
|
||||
classifier ((.proposalThresholds) -> ProposalThresholds e c v)
|
||||
classifier ((.proposalThresholds) -> ProposalThresholds e c tv v)
|
||||
| e < 0 = ExecuteLE0
|
||||
| c < 0 = CreateLE0
|
||||
| tv < 0 = ToVotingLE0
|
||||
| v < 0 = VoteLE0
|
||||
| otherwise = Correct
|
||||
|
||||
|
|
@ -110,24 +112,27 @@ governorDatumValidProperty =
|
|||
let validGT = taggedInteger (0, 1000000000)
|
||||
execute <- validGT
|
||||
create <- validGT
|
||||
toVoting <- validGT
|
||||
vote <- validGT
|
||||
le0 <- taggedInteger (-1000, -1)
|
||||
|
||||
case c of
|
||||
ExecuteLE0 ->
|
||||
-- execute < 0
|
||||
return $ ProposalThresholds le0 create vote
|
||||
return $ ProposalThresholds le0 create toVoting vote
|
||||
CreateLE0 ->
|
||||
-- c < 0
|
||||
return $ ProposalThresholds execute le0 vote
|
||||
return $ ProposalThresholds execute le0 toVoting vote
|
||||
ToVotingLE0 ->
|
||||
return $ ProposalThresholds execute create le0 vote
|
||||
VoteLE0 ->
|
||||
-- vote < 0
|
||||
return $ ProposalThresholds execute create le0
|
||||
return $ ProposalThresholds execute create toVoting le0
|
||||
Correct -> do
|
||||
-- c <= vote < execute
|
||||
nv <- taggedInteger (0, untag execute - 1)
|
||||
nc <- taggedInteger (0, untag nv)
|
||||
return $ ProposalThresholds execute nc nv
|
||||
return $ ProposalThresholds execute nc toVoting nv
|
||||
|
||||
data GovernorPolicyCases
|
||||
= ReferenceUTXONotSpent
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ invalidNewGovernorDatum =
|
|||
GovernorDatum
|
||||
{ proposalThresholds =
|
||||
def
|
||||
{ vote = Tagged (-1)
|
||||
{ toVoting = Tagged (-1)
|
||||
}
|
||||
, nextProposalId = ProposalId 42
|
||||
, proposalTimings = def
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ validGovernorOutputDatum =
|
|||
}
|
||||
|
||||
invalidProposalThresholds :: ProposalThresholds
|
||||
invalidProposalThresholds = ProposalThresholds (-1) (-1) (-1)
|
||||
invalidProposalThresholds = ProposalThresholds (-1) (-1) (-1) (-1)
|
||||
|
||||
invalidMaxTimeRangeWidth :: MaxTimeRangeWidth
|
||||
invalidMaxTimeRangeWidth = MaxTimeRangeWidth 0
|
||||
|
|
|
|||
|
|
@ -120,6 +120,7 @@ mkGovernorOutputDatum ValueInvalid =
|
|||
ProposalThresholds
|
||||
{ execute = -1
|
||||
, create = -1
|
||||
, toVoting = -1
|
||||
, vote = -1
|
||||
}
|
||||
in Just $
|
||||
|
|
|
|||
|
|
@ -679,7 +679,7 @@ getNextState = \case
|
|||
-- | Calculate the number of GTs per stake in order to exceed the minimum limit.
|
||||
compPerStakeGTsForDraft :: NumStake -> Integer
|
||||
compPerStakeGTsForDraft nCosigners =
|
||||
untag (def :: ProposalThresholds).vote
|
||||
untag (def :: ProposalThresholds).toVoting
|
||||
`div` fromIntegral nCosigners + 1
|
||||
|
||||
dummyDatum :: ()
|
||||
|
|
@ -944,7 +944,7 @@ mkInsufficientCosignsBundle nCosigners nEffects =
|
|||
}
|
||||
where
|
||||
insuffcientPerStakeGTs =
|
||||
untag (def :: ProposalThresholds).vote
|
||||
untag (def :: ProposalThresholds).toVoting
|
||||
`div` fromIntegral nCosigners - 1
|
||||
template = mkValidToNextStateBundle nCosigners nEffects False Draft
|
||||
|
||||
|
|
|
|||
541
agora-specs/Sample/Proposal/Unlock.hs
Normal file
541
agora-specs/Sample/Proposal/Unlock.hs
Normal file
|
|
@ -0,0 +1,541 @@
|
|||
{- |
|
||||
Module : Sample.Proposal.UnlockStake
|
||||
Maintainer : connor@mlabs.city
|
||||
Description: Generate sample data for testing the functionalities of unlocking stake and retracting votes
|
||||
|
||||
Sample and utilities for testing the functionalities of unlocking stake and retracting votes
|
||||
-}
|
||||
module Sample.Proposal.Unlock (
|
||||
ParameterBundle (..),
|
||||
StakeRole (..),
|
||||
TimeRange (..),
|
||||
SignedBy (..),
|
||||
TransactionParameters (..),
|
||||
ProposalParameters (..),
|
||||
StakeParameters (..),
|
||||
Validity (..),
|
||||
unlock,
|
||||
mkTestTree,
|
||||
mkValidVoterRetractVotes,
|
||||
mkValidDelegateeRetractVotes,
|
||||
mkValidVoterCreatorRetractVotes,
|
||||
mkValidCreatorRemoveLock,
|
||||
mkValidVoterRemoveLockAfterVoting,
|
||||
mkRetractVotesWhileNotVoting,
|
||||
mkUnockIrrelevantStakes,
|
||||
mkRemoveCreatorLockBeforeFinished,
|
||||
mkCreatorRetractVotes,
|
||||
mkChangeOutputStakeValue,
|
||||
) where
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
import Agora.Governor (Governor (..))
|
||||
import Agora.Proposal (
|
||||
ProposalDatum (..),
|
||||
ProposalEffectGroup,
|
||||
ProposalId (..),
|
||||
ProposalRedeemer (Unlock),
|
||||
ProposalStatus (..),
|
||||
ProposalVotes (..),
|
||||
ResultTag (..),
|
||||
)
|
||||
import Agora.Proposal.Time (ProposalStartingTime (ProposalStartingTime), ProposalTimingConfig (..))
|
||||
import Agora.Scripts (AgoraScripts (..))
|
||||
import Agora.Stake (
|
||||
ProposalLock (..),
|
||||
StakeDatum (..),
|
||||
StakeRedeemer (RetractVotes),
|
||||
)
|
||||
import Data.Default.Class (Default (def))
|
||||
import Data.Map.Strict qualified as StrictMap
|
||||
import Data.Tagged (Tagged (Tagged), untag)
|
||||
import Plutarch.Context (
|
||||
input,
|
||||
normalizeValue,
|
||||
output,
|
||||
script,
|
||||
signedWith,
|
||||
timeRange,
|
||||
txId,
|
||||
withDatum,
|
||||
withRedeemer,
|
||||
withRef,
|
||||
withValue,
|
||||
)
|
||||
import Plutarch.SafeMoney (Discrete (Discrete))
|
||||
import PlutusLedgerApi.V1.Value qualified as Value
|
||||
import PlutusLedgerApi.V2 (
|
||||
Credential (PubKeyCredential),
|
||||
PubKeyHash,
|
||||
TxOutRef (..),
|
||||
)
|
||||
import Sample.Proposal.Shared (stakeTxRef)
|
||||
import Sample.Shared (
|
||||
agoraScripts,
|
||||
governor,
|
||||
minAda,
|
||||
proposalPolicySymbol,
|
||||
proposalValidatorHash,
|
||||
stakeAssetClass,
|
||||
stakeValidatorHash,
|
||||
)
|
||||
import Test.Specification (SpecificationTree, group, testValidator)
|
||||
import Test.Util (CombinableBuilder, closedBoundedInterval, mkSpending, pubKeyHashes)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
votesTemplate :: ProposalVotes
|
||||
votesTemplate =
|
||||
ProposalVotes $
|
||||
StrictMap.fromList
|
||||
[ (ResultTag 0, 0)
|
||||
, (ResultTag 1, 0)
|
||||
]
|
||||
|
||||
-- | Create empty effects for every result tag given the votes.
|
||||
emptyEffectFor ::
|
||||
ProposalVotes ->
|
||||
StrictMap.Map ResultTag ProposalEffectGroup
|
||||
emptyEffectFor (ProposalVotes vs) =
|
||||
StrictMap.fromList $
|
||||
map (,StrictMap.empty) (StrictMap.keys vs)
|
||||
|
||||
-- | The default vote option that will be used by functions in this module.
|
||||
defVoteFor :: ResultTag
|
||||
defVoteFor = ResultTag 0
|
||||
|
||||
-- | The default number of GTs the stake will have.
|
||||
defStakedGTs :: Integer
|
||||
defStakedGTs = 100000
|
||||
|
||||
alteredStakedGTs :: Integer
|
||||
alteredStakedGTs = 100
|
||||
|
||||
-- | Default owner of the stakes.
|
||||
defOwner :: PubKeyHash
|
||||
defOwner = pubKeyHashes !! 1
|
||||
|
||||
defDelegatee :: PubKeyHash
|
||||
defDelegatee = pubKeyHashes !! 2
|
||||
|
||||
defUnknown :: PubKeyHash
|
||||
defUnknown = pubKeyHashes !! 3
|
||||
|
||||
defProposalId :: ProposalId
|
||||
defProposalId = ProposalId 0
|
||||
|
||||
defStartingTime :: ProposalStartingTime
|
||||
defStartingTime = ProposalStartingTime 0
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
data ParameterBundle = ParameterBundle
|
||||
{ proposalParameters :: ProposalParameters
|
||||
, stakeParameters :: StakeParameters
|
||||
, transactionParameters :: TransactionParameters
|
||||
}
|
||||
|
||||
data SignedBy = Owner | Delegatee | Unknown
|
||||
|
||||
data TimeRange = WhileVoting | AfterVoting
|
||||
|
||||
data TransactionParameters = TransactionParameters
|
||||
{ signedBy :: SignedBy
|
||||
, timeRange :: TimeRange
|
||||
}
|
||||
|
||||
data ProposalParameters = ProposalParameters
|
||||
{ proposalStatus :: ProposalStatus
|
||||
, retractVotes :: Bool
|
||||
}
|
||||
|
||||
-- | How a stake has been used on a particular proposal.
|
||||
data StakeRole
|
||||
= -- | The stake was spent to vote for a paraticular option.
|
||||
Voter
|
||||
| -- | The stake was used to create the proposal.
|
||||
Creator
|
||||
| -- | The stake was used to both create and vote for the proposal.
|
||||
Both
|
||||
| -- | The stake has nothing to do with the proposal.
|
||||
Irrelevant
|
||||
deriving stock (Bounded, Enum, Show)
|
||||
|
||||
data StakeParameters = StakeParameters
|
||||
{ numStakes :: Integer
|
||||
, stakeRole :: StakeRole
|
||||
, removeVoterLock :: Bool
|
||||
, removeCreatorLock :: Bool
|
||||
, alterOutputValue :: Bool
|
||||
}
|
||||
|
||||
data Validity = Validity
|
||||
{ forProposalValidator :: Bool
|
||||
, forStakeValidator :: Bool
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
mkStakeRef :: Integer -> TxOutRef
|
||||
mkStakeRef = TxOutRef stakeTxRef
|
||||
|
||||
stakeRedeemer :: StakeRedeemer
|
||||
stakeRedeemer = RetractVotes
|
||||
|
||||
mkStakeInputDatum :: StakeParameters -> StakeDatum
|
||||
mkStakeInputDatum ps =
|
||||
StakeDatum
|
||||
{ stakedAmount = Discrete $ Tagged defStakedGTs
|
||||
, owner = PubKeyCredential defOwner
|
||||
, delegatedTo = Just $ PubKeyCredential defDelegatee
|
||||
, lockedBy = stakeLocks
|
||||
}
|
||||
where
|
||||
stakeLocks = mkStakeLocks' ps.stakeRole
|
||||
|
||||
mkStakeLocks' Voter = [Voted defProposalId defVoteFor]
|
||||
mkStakeLocks' Creator = [Created defProposalId]
|
||||
mkStakeLocks' Both = mkStakeLocks' Voter <> mkStakeLocks' Creator
|
||||
mkStakeLocks' Irrelevant =
|
||||
let ProposalId pid = defProposalId
|
||||
ResultTag vid = defVoteFor
|
||||
in [ Voted (ProposalId $ pid + 1) (ResultTag $ vid + 1)
|
||||
, Created (ProposalId $ pid + 1)
|
||||
]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
proposalRef :: TxOutRef
|
||||
proposalRef = TxOutRef stakeTxRef 0
|
||||
|
||||
proposalRedeemer :: ProposalRedeemer
|
||||
proposalRedeemer = Unlock
|
||||
|
||||
mkProposalInputDatum ::
|
||||
StakeParameters ->
|
||||
ProposalParameters ->
|
||||
ProposalDatum
|
||||
mkProposalInputDatum sps pps =
|
||||
ProposalDatum
|
||||
{ proposalId = defProposalId
|
||||
, effects = emptyEffectFor votesTemplate
|
||||
, status = pps.proposalStatus
|
||||
, cosigners = [PubKeyCredential $ head pubKeyHashes]
|
||||
, thresholds = def
|
||||
, votes = updatVotes votesTemplate
|
||||
, timingConfig = def
|
||||
, startingTime = defStartingTime
|
||||
}
|
||||
where
|
||||
updatVotes (ProposalVotes vt) =
|
||||
ProposalVotes $
|
||||
StrictMap.adjust
|
||||
(+ sps.numStakes * defStakedGTs)
|
||||
defVoteFor
|
||||
vt
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
unlock :: forall b. CombinableBuilder b => ParameterBundle -> b
|
||||
unlock ps = builder
|
||||
where
|
||||
pst = Value.singleton proposalPolicySymbol "" 1
|
||||
|
||||
proposalInputDatum =
|
||||
mkProposalInputDatum
|
||||
ps.stakeParameters
|
||||
ps.proposalParameters
|
||||
|
||||
proposalOutputDatum =
|
||||
if ps.proposalParameters.retractVotes
|
||||
then proposalInputDatum {votes = votesTemplate}
|
||||
else proposalInputDatum
|
||||
|
||||
proposalValue = normalizeValue $ pst <> minAda
|
||||
|
||||
proposalBuilder :: b
|
||||
proposalBuilder =
|
||||
mconcat
|
||||
[ input $
|
||||
mconcat
|
||||
[ script proposalValidatorHash
|
||||
, withValue proposalValue
|
||||
, withDatum proposalInputDatum
|
||||
, withRef proposalRef
|
||||
, withRedeemer proposalRedeemer
|
||||
]
|
||||
, output $
|
||||
mconcat
|
||||
[ script proposalValidatorHash
|
||||
, withValue proposalValue
|
||||
, withDatum proposalOutputDatum
|
||||
]
|
||||
]
|
||||
|
||||
---
|
||||
|
||||
sst = Value.assetClassValue stakeAssetClass 1
|
||||
|
||||
stakeInputDatum = mkStakeInputDatum ps.stakeParameters
|
||||
|
||||
removeLocks v c =
|
||||
filter $
|
||||
not
|
||||
. ( \case
|
||||
Created pid -> c && pid == defProposalId
|
||||
Voted pid _ -> v && pid == defProposalId
|
||||
)
|
||||
|
||||
stakeOutputDatum =
|
||||
stakeInputDatum
|
||||
{ lockedBy =
|
||||
removeLocks
|
||||
ps.stakeParameters.removeVoterLock
|
||||
ps.stakeParameters.removeCreatorLock
|
||||
stakeInputDatum.lockedBy
|
||||
}
|
||||
|
||||
mkStakeValue gt =
|
||||
normalizeValue $
|
||||
mconcat
|
||||
[ minAda
|
||||
, sst
|
||||
, Value.assetClassValue
|
||||
(untag governor.gtClassRef)
|
||||
gt
|
||||
]
|
||||
|
||||
stakeInputValue = mkStakeValue defStakedGTs
|
||||
|
||||
stakeOutputValue =
|
||||
mkStakeValue $
|
||||
if ps.stakeParameters.alterOutputValue
|
||||
then alteredStakedGTs
|
||||
else defStakedGTs
|
||||
|
||||
stakeBuilder :: b
|
||||
stakeBuilder =
|
||||
foldMap
|
||||
( \i ->
|
||||
mconcat
|
||||
[ input $
|
||||
mconcat
|
||||
[ script stakeValidatorHash
|
||||
, withValue stakeInputValue
|
||||
, withDatum stakeInputDatum
|
||||
, withRef $ mkStakeRef i
|
||||
]
|
||||
, output $
|
||||
mconcat
|
||||
[ script stakeValidatorHash
|
||||
, withValue stakeOutputValue
|
||||
, withDatum stakeOutputDatum
|
||||
]
|
||||
]
|
||||
)
|
||||
[1 .. ps.stakeParameters.numStakes]
|
||||
|
||||
---
|
||||
|
||||
time = case ps.transactionParameters.timeRange of
|
||||
WhileVoting ->
|
||||
closedBoundedInterval
|
||||
((def :: ProposalTimingConfig).draftTime + 1)
|
||||
((def :: ProposalTimingConfig).votingTime - 1)
|
||||
AfterVoting ->
|
||||
closedBoundedInterval
|
||||
((def :: ProposalTimingConfig).votingTime + 1)
|
||||
((def :: ProposalTimingConfig).lockingTime - 1)
|
||||
|
||||
sig = case ps.transactionParameters.signedBy of
|
||||
Unknown -> defUnknown
|
||||
Owner -> defOwner
|
||||
Delegatee -> defDelegatee
|
||||
|
||||
---
|
||||
|
||||
builder =
|
||||
mconcat
|
||||
[ txId "388bc0b897b3dadcd479da4c88291de4113a50b72ddbed001faf7fc03f11bc52"
|
||||
, proposalBuilder
|
||||
, stakeBuilder
|
||||
, signedWith sig
|
||||
, timeRange time
|
||||
]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
{- | Create a test tree that runs both the stake validator and the proposal
|
||||
validator.
|
||||
-}
|
||||
mkTestTree :: String -> ParameterBundle -> Validity -> SpecificationTree
|
||||
mkTestTree name ps val = group name [stake, proposal]
|
||||
where
|
||||
spend = mkSpending unlock ps
|
||||
|
||||
stake =
|
||||
testValidator
|
||||
val.forStakeValidator
|
||||
"stake"
|
||||
agoraScripts.compiledStakeValidator
|
||||
(mkStakeInputDatum ps.stakeParameters)
|
||||
stakeRedeemer
|
||||
(spend $ mkStakeRef 1)
|
||||
|
||||
proposal =
|
||||
testValidator
|
||||
val.forProposalValidator
|
||||
"proposal"
|
||||
agoraScripts.compiledProposalValidator
|
||||
(mkProposalInputDatum ps.stakeParameters ps.proposalParameters)
|
||||
proposalRedeemer
|
||||
(spend proposalRef)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
mkValidVoterRetractVotes :: Integer -> ParameterBundle
|
||||
mkValidVoterRetractVotes i =
|
||||
ParameterBundle
|
||||
{ proposalParameters =
|
||||
ProposalParameters
|
||||
{ proposalStatus = VotingReady
|
||||
, retractVotes = True
|
||||
}
|
||||
, stakeParameters =
|
||||
StakeParameters
|
||||
{ numStakes = i
|
||||
, stakeRole = Voter
|
||||
, removeVoterLock = True
|
||||
, removeCreatorLock = False
|
||||
, alterOutputValue = False
|
||||
}
|
||||
, transactionParameters =
|
||||
TransactionParameters
|
||||
{ signedBy = Owner
|
||||
, timeRange =
|
||||
WhileVoting
|
||||
}
|
||||
}
|
||||
|
||||
mkValidDelegateeRetractVotes :: Integer -> ParameterBundle
|
||||
mkValidDelegateeRetractVotes i =
|
||||
let template = mkValidVoterRetractVotes i
|
||||
in template
|
||||
{ transactionParameters =
|
||||
template.transactionParameters
|
||||
{ signedBy = Delegatee
|
||||
}
|
||||
}
|
||||
|
||||
mkValidVoterCreatorRetractVotes :: Integer -> ParameterBundle
|
||||
mkValidVoterCreatorRetractVotes i =
|
||||
let template = mkValidVoterRetractVotes i
|
||||
in template
|
||||
{ stakeParameters =
|
||||
template.stakeParameters
|
||||
{ stakeRole = Both
|
||||
}
|
||||
}
|
||||
|
||||
mkValidCreatorRemoveLock :: Integer -> ParameterBundle
|
||||
mkValidCreatorRemoveLock i =
|
||||
let template = mkValidVoterRetractVotes i
|
||||
in template
|
||||
{ proposalParameters =
|
||||
template.proposalParameters
|
||||
{ proposalStatus = Finished
|
||||
, retractVotes = False
|
||||
}
|
||||
, stakeParameters =
|
||||
template.stakeParameters
|
||||
{ stakeRole = Creator
|
||||
, removeCreatorLock = True
|
||||
}
|
||||
, transactionParameters =
|
||||
template.transactionParameters
|
||||
{ timeRange = AfterVoting
|
||||
}
|
||||
}
|
||||
|
||||
mkValidVoterRemoveLockAfterVoting :: Integer -> ParameterBundle
|
||||
mkValidVoterRemoveLockAfterVoting i =
|
||||
let template = mkValidVoterRetractVotes i
|
||||
in template
|
||||
{ proposalParameters =
|
||||
template.proposalParameters
|
||||
{ proposalStatus = Finished
|
||||
, retractVotes = False
|
||||
}
|
||||
, transactionParameters =
|
||||
template.transactionParameters
|
||||
{ timeRange = AfterVoting
|
||||
}
|
||||
}
|
||||
|
||||
mkRetractVotesWhileNotVoting :: Integer -> [ParameterBundle]
|
||||
mkRetractVotesWhileNotVoting i =
|
||||
let template = mkValidVoterRetractVotes i
|
||||
in map
|
||||
( \s ->
|
||||
template
|
||||
{ proposalParameters =
|
||||
template.proposalParameters
|
||||
{ proposalStatus = s
|
||||
}
|
||||
}
|
||||
)
|
||||
[Draft, Locked, Finished]
|
||||
|
||||
mkUnockIrrelevantStakes :: Integer -> ParameterBundle
|
||||
mkUnockIrrelevantStakes i =
|
||||
let template = mkValidVoterRetractVotes i
|
||||
in template
|
||||
{ stakeParameters =
|
||||
template.stakeParameters
|
||||
{ stakeRole = Irrelevant
|
||||
, removeCreatorLock = True
|
||||
}
|
||||
}
|
||||
|
||||
mkRemoveCreatorLockBeforeFinished :: Integer -> [ParameterBundle]
|
||||
mkRemoveCreatorLockBeforeFinished i =
|
||||
let template = mkValidCreatorRemoveLock i
|
||||
in map
|
||||
( \s ->
|
||||
template
|
||||
{ proposalParameters =
|
||||
template.proposalParameters
|
||||
{ proposalStatus = s
|
||||
}
|
||||
}
|
||||
)
|
||||
[Draft, VotingReady, Locked]
|
||||
|
||||
mkCreatorRetractVotes :: Integer -> ParameterBundle
|
||||
mkCreatorRetractVotes i =
|
||||
let template = mkValidVoterRetractVotes i
|
||||
in template
|
||||
{ proposalParameters =
|
||||
template.proposalParameters
|
||||
{ proposalStatus = VotingReady
|
||||
}
|
||||
, stakeParameters =
|
||||
template.stakeParameters
|
||||
{ stakeRole = Creator
|
||||
}
|
||||
, transactionParameters =
|
||||
template.transactionParameters
|
||||
{ timeRange = WhileVoting
|
||||
}
|
||||
}
|
||||
|
||||
mkChangeOutputStakeValue :: Integer -> ParameterBundle
|
||||
mkChangeOutputStakeValue i =
|
||||
let template = mkValidVoterRetractVotes i
|
||||
in template
|
||||
{ stakeParameters =
|
||||
template.stakeParameters
|
||||
{ alterOutputValue = True
|
||||
}
|
||||
}
|
||||
|
|
@ -1,559 +0,0 @@
|
|||
{- |
|
||||
Module : Sample.Proposal.UnlockStake
|
||||
Maintainer : connor@mlabs.city
|
||||
Description: Generate sample data for testing the functionalities of unlocking stake and retracting votes
|
||||
|
||||
Sample and utilities for testing the functionalities of unlocking stake and retracting votes
|
||||
-}
|
||||
module Sample.Proposal.UnlockStake (
|
||||
StakeRole (..),
|
||||
Parameters (..),
|
||||
unlockStake,
|
||||
mkTestTree,
|
||||
mkVoterRetractVotesWhileVotingParameters,
|
||||
mkVoterCreatorRetractVotesWhileVotingParameters,
|
||||
mkCreatorRemoveCreatorLocksWhenFinishedParameters,
|
||||
mkVoterCreatorRemoveAllLocksWhenFinishedParameters,
|
||||
mkVoterUnlockStakeAfterVotingParameters,
|
||||
mkVoterCreatorRemoveVoteLocksWhenLockedParameters,
|
||||
mkRetractVotesWhileNotVoting,
|
||||
mkUnockIrrelevantStakeParameters,
|
||||
mkRemoveCreatorLockBeforeFinishedParameters,
|
||||
mkRetractVotesWithCreatorStakeParamaters,
|
||||
mkAlterStakeParameters,
|
||||
) where
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
import Agora.Governor (Governor (..))
|
||||
import Agora.Proposal (
|
||||
ProposalDatum (..),
|
||||
ProposalEffectGroup,
|
||||
ProposalId (..),
|
||||
ProposalRedeemer (Unlock),
|
||||
ProposalStatus (..),
|
||||
ProposalVotes (..),
|
||||
ResultTag (..),
|
||||
)
|
||||
import Agora.Proposal.Time (ProposalStartingTime (ProposalStartingTime))
|
||||
import Agora.SafeMoney (GTTag)
|
||||
import Agora.Scripts (AgoraScripts (..))
|
||||
import Agora.Stake (
|
||||
ProposalLock (..),
|
||||
StakeDatum (..),
|
||||
StakeRedeemer (RetractVotes),
|
||||
)
|
||||
import Data.Default.Class (Default (def))
|
||||
import Data.Map.Strict qualified as StrictMap
|
||||
import Data.Tagged (untag)
|
||||
import Plutarch.Context (
|
||||
input,
|
||||
output,
|
||||
script,
|
||||
signedWith,
|
||||
txId,
|
||||
withDatum,
|
||||
withRedeemer,
|
||||
withRef,
|
||||
withValue,
|
||||
)
|
||||
import Plutarch.SafeMoney (Discrete)
|
||||
import PlutusLedgerApi.V1.Value qualified as Value
|
||||
import PlutusLedgerApi.V2 (
|
||||
Credential (PubKeyCredential),
|
||||
PubKeyHash,
|
||||
TxOutRef (..),
|
||||
)
|
||||
import Sample.Proposal.Shared (stakeTxRef)
|
||||
import Sample.Shared (
|
||||
agoraScripts,
|
||||
fromDiscrete,
|
||||
governor,
|
||||
minAda,
|
||||
proposalPolicySymbol,
|
||||
proposalValidatorHash,
|
||||
signer,
|
||||
stakeAssetClass,
|
||||
stakeValidatorHash,
|
||||
)
|
||||
import Test.Specification (SpecificationTree, group, testValidator)
|
||||
import Test.Util (CombinableBuilder, mkSpending, sortValue)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
-- | The template "shape" that votes of proposals generated by 'mkProposalDatumPair' have.
|
||||
votesTemplate :: ProposalVotes
|
||||
votesTemplate =
|
||||
ProposalVotes $
|
||||
StrictMap.fromList
|
||||
[ (ResultTag 0, 0)
|
||||
, (ResultTag 1, 0)
|
||||
]
|
||||
|
||||
-- | Create empty effects for every result tag given the votes.
|
||||
emptyEffectFor ::
|
||||
ProposalVotes ->
|
||||
StrictMap.Map ResultTag ProposalEffectGroup
|
||||
emptyEffectFor (ProposalVotes vs) =
|
||||
StrictMap.fromList $
|
||||
map (,StrictMap.empty) (StrictMap.keys vs)
|
||||
|
||||
-- | The default vote option that will be used by functions in this module.
|
||||
defVoteFor :: ResultTag
|
||||
defVoteFor = ResultTag 0
|
||||
|
||||
-- | The default number of GTs the stake will have.
|
||||
defStakedGTs :: Discrete GTTag
|
||||
defStakedGTs = 100000
|
||||
|
||||
{- | If 'Parameters.alterOutputStake' is set to true, the
|
||||
'StakeDatum.stakedAmount' will be set to this.
|
||||
-}
|
||||
alteredStakedGTs :: Discrete GTTag
|
||||
alteredStakedGTs = 100
|
||||
|
||||
-- | Default owner of the stakes.
|
||||
defOwner :: PubKeyHash
|
||||
defOwner = signer
|
||||
|
||||
-- | How a stake has been used on a particular proposal.
|
||||
data StakeRole
|
||||
= -- | The stake was spent to vote for a paraticular option.
|
||||
Voter
|
||||
| -- | The stake was used to create the proposal.
|
||||
Creator
|
||||
| -- | The stake was used to both create and vote for the proposal.
|
||||
Both
|
||||
| -- | The stake has nothing to do with the proposal.
|
||||
Irrelevant
|
||||
deriving stock (Bounded, Enum, Show)
|
||||
|
||||
-- | Parameters for creating a 'TxOut' that unlocks a stake.
|
||||
data Parameters = Parameters
|
||||
{ proposalCount :: Integer
|
||||
-- ^ The number of proposals in the 'TxOut'.
|
||||
, stakeRole :: StakeRole
|
||||
-- ^ The role of the stake we're unlocking.
|
||||
, retractVotes :: Bool
|
||||
-- ^ Whether to retract votes or not.
|
||||
, removeVoterLock :: Bool
|
||||
-- ^ Remove the voter locks from the input stake.
|
||||
, removeCreatorLock :: Bool
|
||||
-- ^ Remove the creator locks from the input stake.
|
||||
, proposalStatus :: ProposalStatus
|
||||
-- ^ The state of all the proposals.
|
||||
, alterOutputStake :: Bool
|
||||
}
|
||||
|
||||
-- | Iterate over the proposal id of every proposal, given the number of proposals.
|
||||
forEachProposalId :: Parameters -> (ProposalId -> a) -> [a]
|
||||
forEachProposalId ps = forEachProposalId' ps.proposalCount
|
||||
where
|
||||
forEachProposalId' :: Integer -> (ProposalId -> a) -> [a]
|
||||
forEachProposalId' 0 _ = error "zero proposal"
|
||||
forEachProposalId' n f = f . ProposalId <$> [0 .. n - 1]
|
||||
|
||||
-- | Create locks for the input stake given the parameters.
|
||||
mkInputStakeLocks :: Parameters -> [ProposalLock]
|
||||
mkInputStakeLocks ps = mconcat $ forEachProposalId ps $ mkStakeLocksFor ps.stakeRole
|
||||
where
|
||||
mkStakeLocksFor :: StakeRole -> ProposalId -> [ProposalLock]
|
||||
mkStakeLocksFor sr pid =
|
||||
let voted = [Voted pid defVoteFor]
|
||||
created = [Created pid]
|
||||
in case sr of
|
||||
Voter -> voted
|
||||
Creator -> created
|
||||
Both -> voted <> created
|
||||
_ -> []
|
||||
|
||||
-- | Create locks for the output stake by removing locks from the input locks.
|
||||
mkOutputStakeLocks :: Parameters -> [ProposalLock]
|
||||
mkOutputStakeLocks ps =
|
||||
filter
|
||||
( \lock -> not $ case lock of
|
||||
Voted _ _ -> ps.removeVoterLock
|
||||
Created _ -> ps.removeCreatorLock
|
||||
)
|
||||
inputLocks
|
||||
where
|
||||
inputLocks = mkInputStakeLocks ps
|
||||
|
||||
-- | Create the stake input datum given the parameters.
|
||||
mkStakeInputDatum :: Parameters -> StakeDatum
|
||||
mkStakeInputDatum ps =
|
||||
StakeDatum
|
||||
{ stakedAmount = defStakedGTs
|
||||
, owner = PubKeyCredential defOwner
|
||||
, delegatedTo = Nothing
|
||||
, lockedBy = mkInputStakeLocks ps
|
||||
}
|
||||
|
||||
-- | Create stake output datum given the parameters.
|
||||
mkStakeOutputDatum :: Parameters -> StakeDatum
|
||||
mkStakeOutputDatum ps =
|
||||
let template = mkStakeInputDatum ps
|
||||
stakedAmount' =
|
||||
if ps.alterOutputStake
|
||||
then alteredStakedGTs
|
||||
else defStakedGTs
|
||||
in template
|
||||
{ stakedAmount = stakedAmount'
|
||||
, lockedBy = mkOutputStakeLocks ps
|
||||
}
|
||||
|
||||
-- | Generate some input proposals and their corresponding output proposals.
|
||||
mkProposals :: Parameters -> [(ProposalDatum, ProposalDatum)]
|
||||
mkProposals ps = forEachProposalId ps $ mkProposalDatumPair ps
|
||||
|
||||
-- | Create the input proposal datum.
|
||||
mkProposalInputDatum :: Parameters -> ProposalId -> ProposalDatum
|
||||
mkProposalInputDatum p pid = fst $ mkProposalDatumPair p pid
|
||||
|
||||
-- | Create a input proposal and its corresponding output proposal.
|
||||
mkProposalDatumPair ::
|
||||
Parameters ->
|
||||
ProposalId ->
|
||||
(ProposalDatum, ProposalDatum)
|
||||
mkProposalDatumPair params pid =
|
||||
let inputVotes = mkInputVotes params.stakeRole $ fromDiscrete defStakedGTs
|
||||
|
||||
input =
|
||||
ProposalDatum
|
||||
{ proposalId = pid
|
||||
, effects = emptyEffectFor votesTemplate
|
||||
, status = params.proposalStatus
|
||||
, cosigners = [PubKeyCredential defOwner]
|
||||
, thresholds = def
|
||||
, votes = inputVotes
|
||||
, timingConfig = def
|
||||
, startingTime = ProposalStartingTime 0
|
||||
}
|
||||
|
||||
output =
|
||||
if params.retractVotes
|
||||
then input {votes = votesTemplate}
|
||||
else input
|
||||
in (input, output)
|
||||
where
|
||||
-- Assemble the votes of the input proposal based on 'votesTemplate'.
|
||||
mkInputVotes ::
|
||||
StakeRole ->
|
||||
-- The staked amount/votes.
|
||||
Integer ->
|
||||
ProposalVotes
|
||||
mkInputVotes Creator _ =
|
||||
ProposalVotes $
|
||||
StrictMap.adjust (const 1000) defVoteFor $
|
||||
votesTemplate.getProposalVotes
|
||||
mkInputVotes Irrelevant _ = votesTemplate
|
||||
mkInputVotes _ vc =
|
||||
ProposalVotes $
|
||||
StrictMap.adjust (const vc) defVoteFor $
|
||||
votesTemplate.getProposalVotes
|
||||
|
||||
-- | Create a 'TxInfo' that tries to unlock a stake.
|
||||
unlockStake :: forall b. CombinableBuilder b => Parameters -> b
|
||||
unlockStake ps =
|
||||
let pst = Value.singleton proposalPolicySymbol "" 1
|
||||
sst = Value.assetClassValue stakeAssetClass 1
|
||||
|
||||
pIODatums = mkProposals ps
|
||||
|
||||
proposals =
|
||||
foldMap
|
||||
( \((i, o), idx) ->
|
||||
mconcat
|
||||
[ input $
|
||||
mconcat
|
||||
[ script proposalValidatorHash
|
||||
, withValue pst
|
||||
, withDatum i
|
||||
, withRef (mkProposalRef idx)
|
||||
, withRedeemer proposalRedeemer
|
||||
]
|
||||
, output $
|
||||
mconcat
|
||||
[ script proposalValidatorHash
|
||||
, withValue (sortValue $ pst <> minAda)
|
||||
, withDatum o
|
||||
]
|
||||
]
|
||||
)
|
||||
(zip pIODatums [0 ..])
|
||||
|
||||
stakeValue =
|
||||
sortValue $
|
||||
mconcat
|
||||
[ Value.assetClassValue
|
||||
(untag governor.gtClassRef)
|
||||
(fromDiscrete defStakedGTs)
|
||||
, sst
|
||||
, minAda
|
||||
]
|
||||
|
||||
sInDatum = mkStakeInputDatum ps
|
||||
sOutDatum = mkStakeOutputDatum ps
|
||||
|
||||
stakes =
|
||||
mconcat
|
||||
[ input $
|
||||
mconcat
|
||||
[ script stakeValidatorHash
|
||||
, withValue stakeValue
|
||||
, withDatum sInDatum
|
||||
, withRef stakeRef
|
||||
]
|
||||
, output $
|
||||
mconcat
|
||||
[ script stakeValidatorHash
|
||||
, withValue stakeValue
|
||||
, withDatum sOutDatum
|
||||
]
|
||||
]
|
||||
|
||||
builder =
|
||||
mconcat
|
||||
[ txId "388bc0b897b3dadcd479da4c88291de4113a50b72ddbed001faf7fc03f11bc52"
|
||||
, proposals
|
||||
, stakes
|
||||
, signedWith defOwner
|
||||
]
|
||||
in builder
|
||||
|
||||
-- | Reference to the stake UTXO.
|
||||
stakeRef :: TxOutRef
|
||||
stakeRef = TxOutRef stakeTxRef 1
|
||||
|
||||
-- | Generate the reference to a proposal UTXOs, given the index of the proposal.
|
||||
mkProposalRef :: Int -> TxOutRef
|
||||
mkProposalRef offset = TxOutRef stakeTxRef $ 2 + fromIntegral offset
|
||||
|
||||
-- | Proposal redeemer used by 'mkTestTree', in this case it's always 'Unlock'.
|
||||
proposalRedeemer :: ProposalRedeemer
|
||||
proposalRedeemer = Unlock
|
||||
|
||||
-- | Stake redeemer used by 'mkTestTree', in this case it's always 'RetractVotes'.
|
||||
stakeRedeemer :: StakeRedeemer
|
||||
stakeRedeemer = RetractVotes
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
{- | Legal parameters that retract votes while the proposals is in 'VotingReady'
|
||||
state, and also remove voter locks from the stake, which is
|
||||
used to vote on the proposals.
|
||||
-}
|
||||
mkVoterRetractVotesWhileVotingParameters :: Integer -> Parameters
|
||||
mkVoterRetractVotesWhileVotingParameters nProposals =
|
||||
Parameters
|
||||
{ proposalCount = nProposals
|
||||
, stakeRole = Voter
|
||||
, retractVotes = True
|
||||
, removeVoterLock = True
|
||||
, removeCreatorLock = False
|
||||
, proposalStatus = VotingReady
|
||||
, alterOutputStake = False
|
||||
}
|
||||
|
||||
{- | Legal parameters that retract votes while the proposals is in 'VotingReady'
|
||||
state, and also remove voter locks from the stake, which is
|
||||
used to both create and vote on the proposals.
|
||||
-}
|
||||
mkVoterCreatorRetractVotesWhileVotingParameters :: Integer -> Parameters
|
||||
mkVoterCreatorRetractVotesWhileVotingParameters nProposals =
|
||||
Parameters
|
||||
{ proposalCount = nProposals
|
||||
, stakeRole = Both
|
||||
, retractVotes = True
|
||||
, removeVoterLock = True
|
||||
, removeCreatorLock = False
|
||||
, proposalStatus = VotingReady
|
||||
, alterOutputStake = False
|
||||
}
|
||||
|
||||
{- | Legal parameters that remove creator locks from the stake while the
|
||||
proposals is in 'Finished' state. The stake was only used for creating
|
||||
the proposals.
|
||||
-}
|
||||
mkCreatorRemoveCreatorLocksWhenFinishedParameters :: Integer -> Parameters
|
||||
mkCreatorRemoveCreatorLocksWhenFinishedParameters nProposals =
|
||||
Parameters
|
||||
{ proposalCount = nProposals
|
||||
, stakeRole = Creator
|
||||
, retractVotes = False
|
||||
, removeVoterLock = False
|
||||
, removeCreatorLock = True
|
||||
, proposalStatus = Finished
|
||||
, alterOutputStake = False
|
||||
}
|
||||
|
||||
{- | Legal parameters that remove voter and creator locks from the stake while
|
||||
the proposals is in 'Finished' state. The stake was used for creating
|
||||
and voting on the proposals.
|
||||
-}
|
||||
mkVoterCreatorRemoveAllLocksWhenFinishedParameters :: Integer -> Parameters
|
||||
mkVoterCreatorRemoveAllLocksWhenFinishedParameters nProposals =
|
||||
Parameters
|
||||
{ proposalCount = nProposals
|
||||
, stakeRole = Both
|
||||
, retractVotes = False
|
||||
, removeVoterLock = True
|
||||
, removeCreatorLock = True
|
||||
, proposalStatus = Finished
|
||||
, alterOutputStake = False
|
||||
}
|
||||
|
||||
{- Legal parameters that remove voter locks from the stake after the voting
|
||||
phrase. The stake was used only for voting on the proposals.
|
||||
-}
|
||||
mkVoterUnlockStakeAfterVotingParameters :: Integer -> [Parameters]
|
||||
mkVoterUnlockStakeAfterVotingParameters nProposals =
|
||||
map
|
||||
( \st ->
|
||||
Parameters
|
||||
{ proposalCount = nProposals
|
||||
, stakeRole = Voter
|
||||
, retractVotes = False
|
||||
, removeVoterLock = True
|
||||
, removeCreatorLock = False
|
||||
, proposalStatus = st
|
||||
, alterOutputStake = False
|
||||
}
|
||||
)
|
||||
[Locked, Finished]
|
||||
|
||||
{- Legal parameters that remove voter locks whenproposals are in phrase.
|
||||
The stake was used for crating and voting on the proposals.
|
||||
-}
|
||||
mkVoterCreatorRemoveVoteLocksWhenLockedParameters :: Integer -> Parameters
|
||||
mkVoterCreatorRemoveVoteLocksWhenLockedParameters nProposals =
|
||||
Parameters
|
||||
{ proposalCount = nProposals
|
||||
, stakeRole = Both
|
||||
, retractVotes = False
|
||||
, removeVoterLock = True
|
||||
, removeCreatorLock = False
|
||||
, proposalStatus = Locked
|
||||
, alterOutputStake = False
|
||||
}
|
||||
|
||||
{- | Illegal parameters that retract votes when the proposals are not in voting
|
||||
phrase.
|
||||
-}
|
||||
mkRetractVotesWhileNotVoting :: Integer -> [Parameters]
|
||||
mkRetractVotesWhileNotVoting nProposals = do
|
||||
role <- enumFrom Voter
|
||||
status <- [Draft, Locked, Finished]
|
||||
|
||||
pure $
|
||||
Parameters
|
||||
{ proposalCount = nProposals
|
||||
, stakeRole = role
|
||||
, retractVotes = True
|
||||
, removeVoterLock = True
|
||||
, removeCreatorLock = False
|
||||
, proposalStatus = status
|
||||
, alterOutputStake = False
|
||||
}
|
||||
|
||||
{- | Illegal parameter that try to unlock a stake that has nothing to do with
|
||||
the proposals.
|
||||
-}
|
||||
mkUnockIrrelevantStakeParameters :: Integer -> [Parameters]
|
||||
mkUnockIrrelevantStakeParameters nProposals = do
|
||||
status <- [Draft, VotingReady, Locked, Finished]
|
||||
retractVotes <- [True, False]
|
||||
|
||||
pure $
|
||||
Parameters
|
||||
{ proposalCount = nProposals
|
||||
, stakeRole = Irrelevant
|
||||
, retractVotes = retractVotes
|
||||
, removeVoterLock = True
|
||||
, removeCreatorLock = True
|
||||
, proposalStatus = status
|
||||
, alterOutputStake = False
|
||||
}
|
||||
|
||||
{- | Illegal parameters that remove the creator locks before the proposals are
|
||||
'Finished'.
|
||||
-}
|
||||
mkRemoveCreatorLockBeforeFinishedParameters :: Integer -> [Parameters]
|
||||
mkRemoveCreatorLockBeforeFinishedParameters nProposals = do
|
||||
status <- [Draft, VotingReady, Locked]
|
||||
|
||||
pure $
|
||||
Parameters
|
||||
{ proposalCount = nProposals
|
||||
, stakeRole = Creator
|
||||
, retractVotes = False
|
||||
, removeVoterLock = False
|
||||
, removeCreatorLock = True
|
||||
, proposalStatus = status
|
||||
, alterOutputStake = False
|
||||
}
|
||||
|
||||
{- | Illegal parameters that try to retract votes with a stake that was only used
|
||||
for creating the proposals.
|
||||
-}
|
||||
mkRetractVotesWithCreatorStakeParamaters :: Integer -> Parameters
|
||||
mkRetractVotesWithCreatorStakeParamaters nProposals =
|
||||
Parameters
|
||||
{ proposalCount = nProposals
|
||||
, stakeRole = Creator
|
||||
, retractVotes = True
|
||||
, removeVoterLock = True
|
||||
, removeCreatorLock = True
|
||||
, proposalStatus = VotingReady
|
||||
, alterOutputStake = False
|
||||
}
|
||||
|
||||
{- | Illegal parameters that try to change the 'StakeDatum.stakedAmount' field of
|
||||
the output stake datum.
|
||||
-}
|
||||
mkAlterStakeParameters :: Integer -> [Parameters]
|
||||
mkAlterStakeParameters nProposals = do
|
||||
role <- enumFrom Voter
|
||||
status <- [Draft, Locked, Finished]
|
||||
|
||||
pure $
|
||||
Parameters
|
||||
{ proposalCount = nProposals
|
||||
, stakeRole = role
|
||||
, retractVotes = True
|
||||
, removeVoterLock = True
|
||||
, removeCreatorLock = False
|
||||
, proposalStatus = status
|
||||
, alterOutputStake = True
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
{- | Create a test tree that runs both the stake validator and the proposal
|
||||
validator.
|
||||
-}
|
||||
mkTestTree :: String -> Parameters -> Bool -> SpecificationTree
|
||||
mkTestTree name ps isValid = group name [stake, proposal]
|
||||
where
|
||||
spend = mkSpending unlockStake ps
|
||||
|
||||
stake =
|
||||
testValidator
|
||||
(not ps.alterOutputStake)
|
||||
"stake"
|
||||
agoraScripts.compiledStakeValidator
|
||||
(mkStakeInputDatum ps)
|
||||
stakeRedeemer
|
||||
(spend stakeRef)
|
||||
|
||||
proposal =
|
||||
let idx = 0
|
||||
pid = ProposalId $ fromIntegral idx
|
||||
ref = mkProposalRef idx
|
||||
in testValidator
|
||||
isValid
|
||||
"proposal"
|
||||
agoraScripts.compiledProposalValidator
|
||||
(mkProposalInputDatum ps pid)
|
||||
proposalRedeemer
|
||||
(spend ref)
|
||||
|
|
@ -2,13 +2,31 @@
|
|||
Module : Sample.Proposal.Vote
|
||||
Maintainer : connor@mlabs.city
|
||||
Description: Generate sample data for testing the functionalities of voting on proposals.
|
||||
|
||||
Sample and utilities for testing the functionalities of voting on proposals.
|
||||
-}
|
||||
module Sample.Proposal.Vote (
|
||||
validVoteParameters,
|
||||
ParameterBundle (..),
|
||||
VoteParameters (..),
|
||||
StakeParameters (..),
|
||||
StakeInputParameters (..),
|
||||
StakeOutputParameters (..),
|
||||
NumProposals (..),
|
||||
ProposalParameters (..),
|
||||
TransactionParameters (..),
|
||||
Validity (..),
|
||||
vote,
|
||||
mkTestTree,
|
||||
validVoteAsDelegateParameters,
|
||||
mkValidOwnerVoteBundle,
|
||||
mkValidDelegateeVoteBundle,
|
||||
transparentAssets,
|
||||
transactionNotAuthorized,
|
||||
voteForNonexistentOutcome,
|
||||
noProposal,
|
||||
moreThanOneProposals,
|
||||
invalidLocks,
|
||||
destroyStakes,
|
||||
insufficientAmount,
|
||||
insufficientAmount1,
|
||||
) where
|
||||
|
||||
import Agora.Governor (Governor (..))
|
||||
|
|
@ -26,91 +44,116 @@ import Agora.Proposal.Time (
|
|||
)
|
||||
import Agora.Scripts (AgoraScripts (..))
|
||||
import Agora.Stake (
|
||||
ProposalLock (..),
|
||||
ProposalLock (Voted),
|
||||
StakeDatum (..),
|
||||
StakeRedeemer (PermitVote),
|
||||
StakeRedeemer (Destroy, PermitVote),
|
||||
)
|
||||
import Data.Default (Default (def))
|
||||
import Data.Map.Strict qualified as StrictMap
|
||||
import Data.Maybe (catMaybes)
|
||||
import Data.Tagged (untag)
|
||||
import Plutarch.Context (
|
||||
input,
|
||||
mint,
|
||||
normalizeValue,
|
||||
output,
|
||||
script,
|
||||
signedWith,
|
||||
timeRange,
|
||||
txId,
|
||||
withDatum,
|
||||
withInlineDatum,
|
||||
withRedeemer,
|
||||
withRef,
|
||||
withValue,
|
||||
)
|
||||
import PlutusLedgerApi.V1.Value qualified as Value
|
||||
import PlutusLedgerApi.V2 (
|
||||
Credential (PubKeyCredential),
|
||||
PubKeyHash,
|
||||
TxOutRef (TxOutRef),
|
||||
)
|
||||
import Sample.Proposal.Shared (proposalTxRef, stakeTxRef)
|
||||
import PlutusLedgerApi.V2 (Credential (PubKeyCredential), PubKeyHash)
|
||||
import PlutusLedgerApi.V2.Contexts (TxOutRef (TxOutRef))
|
||||
import Sample.Proposal.Shared (proposalTxRef)
|
||||
import Sample.Shared (
|
||||
agoraScripts,
|
||||
governor,
|
||||
minAda,
|
||||
proposalPolicySymbol,
|
||||
proposalValidatorHash,
|
||||
signer,
|
||||
stakeAssetClass,
|
||||
stakeValidatorHash,
|
||||
)
|
||||
import Test.Specification (
|
||||
SpecificationTree,
|
||||
group,
|
||||
testValidator,
|
||||
validatorSucceedsWith,
|
||||
)
|
||||
import Test.Specification (SpecificationTree, group, testValidator)
|
||||
import Test.Util (
|
||||
CombinableBuilder,
|
||||
closedBoundedInterval,
|
||||
mkSpending,
|
||||
pubKeyHashes,
|
||||
sortValue,
|
||||
)
|
||||
|
||||
-- | Reference to the proposal UTXO.
|
||||
proposalRef :: TxOutRef
|
||||
proposalRef = TxOutRef proposalTxRef 0
|
||||
|
||||
-- | Reference to the stake UTXO.
|
||||
stakeRef :: TxOutRef
|
||||
stakeRef = TxOutRef stakeTxRef 1
|
||||
|
||||
-- | Parameters for creating a voting transaction.
|
||||
data Parameters = Parameters
|
||||
{ voteFor :: ResultTag
|
||||
-- ^ The outcome the transaction is voting for.
|
||||
, voteCount :: Integer
|
||||
-- ^ The count of votes.
|
||||
, voteAsDelegate :: Bool
|
||||
-- ^ Delegate the stake and use it to vote.
|
||||
data ParameterBundle = ParamerterBundle
|
||||
{ voteParameters :: VoteParameters
|
||||
, stakeParameters :: StakeParameters
|
||||
, proposalParameters :: ProposalParameters
|
||||
, transactionParameters :: TransactionParameters
|
||||
}
|
||||
|
||||
-- | The public key hash of the stake owner.
|
||||
stakeOwner :: PubKeyHash
|
||||
stakeOwner = signer
|
||||
newtype VoteParameters = VoteParameters {voteFor :: ResultTag}
|
||||
|
||||
data StakeParameters = StakeParameters
|
||||
{ numStakes :: Integer
|
||||
, stakeInputParameters :: StakeInputParameters
|
||||
, stakeOutputParameters :: StakeOutputParameters
|
||||
}
|
||||
|
||||
newtype StakeInputParameters = StakeInputParameters
|
||||
{ perStakeGTs :: Integer
|
||||
}
|
||||
|
||||
data StakeOutputParameters = StakeOutputParameters
|
||||
{ burnStakes :: Bool
|
||||
, dontAddNewLock :: Bool
|
||||
, changeGTAmount :: Bool
|
||||
, changeAdaAmount :: Bool
|
||||
}
|
||||
|
||||
data NumProposals = NoProposal | OneProposal | MoreThanOneProposals
|
||||
|
||||
data ProposalParameters = ProposalParameters
|
||||
{ wrongAddedVotes :: Bool
|
||||
, numProposals :: NumProposals
|
||||
}
|
||||
|
||||
data SignedBy = Owner | Delegatee | Unknown
|
||||
|
||||
newtype TransactionParameters = TransactionParameters
|
||||
{ signedBy :: SignedBy
|
||||
}
|
||||
|
||||
data Validity = Validity
|
||||
{ forProposalValidator :: Bool
|
||||
, forStakeValidator :: Bool
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
stakeOwner :: PubKeyHash
|
||||
stakeOwner = head pubKeyHashes
|
||||
|
||||
delegatee :: PubKeyHash
|
||||
delegatee = pubKeyHashes !! 1
|
||||
|
||||
unknownSig :: PubKeyHash
|
||||
unknownSig = pubKeyHashes !! 2
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
-- | The votes of the input proposals.
|
||||
initialVotes :: StrictMap.Map ResultTag Integer
|
||||
initialVotes =
|
||||
StrictMap.fromList
|
||||
[ (ResultTag 0, 42)
|
||||
, (ResultTag 1, 4242)
|
||||
[ (ResultTag 0, 114)
|
||||
, (ResultTag 1, 514)
|
||||
]
|
||||
|
||||
-- | The input proposal datum.
|
||||
proposalInputDatum :: ProposalDatum
|
||||
proposalInputDatum =
|
||||
ProposalDatum
|
||||
{ proposalId = ProposalId 42
|
||||
{ proposalId = ProposalId 22
|
||||
, effects =
|
||||
StrictMap.fromList
|
||||
[ (ResultTag 0, StrictMap.empty)
|
||||
|
|
@ -124,178 +167,388 @@ proposalInputDatum =
|
|||
, startingTime = ProposalStartingTime 0
|
||||
}
|
||||
|
||||
-- | The locks of the input stake.
|
||||
existingLocks :: [ProposalLock]
|
||||
existingLocks =
|
||||
[ Voted (ProposalId 0) (ResultTag 0)
|
||||
, Voted (ProposalId 1) (ResultTag 2)
|
||||
]
|
||||
mkProposalRedeemer :: VoteParameters -> ProposalRedeemer
|
||||
mkProposalRedeemer v = Vote v.voteFor
|
||||
|
||||
delegate :: PubKeyHash
|
||||
delegate = head pubKeyHashes
|
||||
mkProposalRef :: Integer -> TxOutRef
|
||||
mkProposalRef = TxOutRef proposalTxRef
|
||||
|
||||
{- | Set the 'StakeDatum.stakedAmount' according to the number of votes being
|
||||
casted.
|
||||
-}
|
||||
mkStakeInputDatum :: Parameters -> StakeDatum
|
||||
numProposals :: NumProposals -> Integer
|
||||
numProposals NoProposal = 0
|
||||
numProposals OneProposal = 1
|
||||
numProposals MoreThanOneProposals = 2
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
mkStakeRedeemer :: StakeOutputParameters -> StakeRedeemer
|
||||
mkStakeRedeemer params =
|
||||
if params.burnStakes
|
||||
then Destroy
|
||||
else PermitVote
|
||||
|
||||
mkStakeInputDatum :: StakeInputParameters -> StakeDatum
|
||||
mkStakeInputDatum params =
|
||||
StakeDatum
|
||||
{ stakedAmount = fromInteger params.voteCount
|
||||
{ stakedAmount = fromInteger params.perStakeGTs
|
||||
, owner = PubKeyCredential stakeOwner
|
||||
, delegatedTo =
|
||||
if params.voteAsDelegate
|
||||
then Just (PubKeyCredential delegate)
|
||||
else Nothing
|
||||
, lockedBy = existingLocks
|
||||
, delegatedTo = Just (PubKeyCredential delegatee)
|
||||
, lockedBy =
|
||||
[ Voted (ProposalId 0) (ResultTag 0)
|
||||
, Voted (ProposalId 1) (ResultTag 2)
|
||||
]
|
||||
}
|
||||
|
||||
-- | Create the proposal redeemer. In this case @'Vote' _@ will always be used.
|
||||
mkProposalRedeemer :: Parameters -> ProposalRedeemer
|
||||
mkProposalRedeemer params = Vote params.voteFor
|
||||
mkStakeRef :: Integer -> Integer -> TxOutRef
|
||||
mkStakeRef o i = TxOutRef proposalTxRef $ o + i
|
||||
|
||||
-- | Place new proposal locks on the stake.
|
||||
mkNewLock :: Parameters -> ProposalLock
|
||||
mkNewLock params = Voted proposalInputDatum.proposalId params.voteFor
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
{- | The stake redeemer that is used in 'mkTestTree'. In this case it'll always be
|
||||
'PermitVote'.
|
||||
-}
|
||||
stakeRedeemer :: StakeRedeemer
|
||||
stakeRedeemer = PermitVote
|
||||
|
||||
-- | Create a valid transaction that votes on a propsal, given the parameters.
|
||||
vote :: forall b. CombinableBuilder b => Parameters -> b
|
||||
vote :: forall b. CombinableBuilder b => ParameterBundle -> b
|
||||
vote params =
|
||||
let pst = Value.singleton proposalPolicySymbol "" 1
|
||||
sst = Value.assetClassValue stakeAssetClass 1
|
||||
|
||||
---
|
||||
|
||||
stakeInputDatum = mkStakeInputDatum params
|
||||
stakeInputDatum =
|
||||
mkStakeInputDatum
|
||||
params.stakeParameters.stakeInputParameters
|
||||
|
||||
---
|
||||
stakeInputValue =
|
||||
normalizeValue $
|
||||
sst
|
||||
<> Value.assetClassValue
|
||||
(untag governor.gtClassRef)
|
||||
params.stakeParameters.stakeInputParameters.perStakeGTs
|
||||
<> minAda
|
||||
|
||||
updatedVotes :: StrictMap.Map ResultTag Integer
|
||||
updatedVotes = StrictMap.adjust (+ params.voteCount) params.voteFor initialVotes
|
||||
newLock =
|
||||
Voted
|
||||
proposalInputDatum.proposalId
|
||||
params.voteParameters.voteFor
|
||||
|
||||
---
|
||||
updatedLocks =
|
||||
if params.stakeParameters.stakeOutputParameters.dontAddNewLock
|
||||
then stakeInputDatum.lockedBy
|
||||
else newLock : stakeInputDatum.lockedBy
|
||||
|
||||
stakeOutputDatum = stakeInputDatum {lockedBy = updatedLocks}
|
||||
|
||||
stakeOutputValue =
|
||||
let changeAmount cond = if cond then (* 100) else id
|
||||
gtAmount =
|
||||
changeAmount
|
||||
params.stakeParameters.stakeOutputParameters.changeGTAmount
|
||||
params.stakeParameters.stakeInputParameters.perStakeGTs
|
||||
adaAmount =
|
||||
changeAmount
|
||||
params.stakeParameters.stakeOutputParameters.changeAdaAmount
|
||||
10_000_000
|
||||
in normalizeValue $
|
||||
sst
|
||||
<> Value.assetClassValue
|
||||
(untag governor.gtClassRef)
|
||||
gtAmount
|
||||
<> minAda
|
||||
<> Value.singleton "" "" adaAmount
|
||||
|
||||
stakeRedeemer =
|
||||
mkStakeRedeemer params.stakeParameters.stakeOutputParameters
|
||||
|
||||
stakeBuilder :: b
|
||||
stakeBuilder =
|
||||
foldMap
|
||||
( \i ->
|
||||
mconcat
|
||||
[ input $
|
||||
mconcat
|
||||
[ script stakeValidatorHash
|
||||
, withValue stakeInputValue
|
||||
, withInlineDatum stakeInputDatum
|
||||
, withRedeemer stakeRedeemer
|
||||
, withRef $ mkStakeRef numProposals' i
|
||||
]
|
||||
, if params.stakeParameters.stakeOutputParameters.burnStakes
|
||||
then mint $ Value.assetClassValue stakeAssetClass (-1)
|
||||
else
|
||||
output $
|
||||
mconcat
|
||||
[ script stakeValidatorHash
|
||||
, withValue stakeOutputValue
|
||||
, withInlineDatum stakeOutputDatum
|
||||
]
|
||||
]
|
||||
)
|
||||
[1 .. params.stakeParameters.numStakes]
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
numProposals' = numProposals params.proposalParameters.numProposals
|
||||
|
||||
updatedVotes =
|
||||
StrictMap.adjust
|
||||
( ( if params.proposalParameters.wrongAddedVotes
|
||||
then (* 10)
|
||||
else id
|
||||
)
|
||||
. ( +
|
||||
params.stakeParameters.stakeInputParameters.perStakeGTs
|
||||
* params.stakeParameters.numStakes
|
||||
)
|
||||
)
|
||||
params.voteParameters.voteFor
|
||||
initialVotes
|
||||
|
||||
proposalOutputDatum :: ProposalDatum
|
||||
proposalOutputDatum =
|
||||
proposalInputDatum
|
||||
{ votes = ProposalVotes updatedVotes
|
||||
}
|
||||
|
||||
---
|
||||
proposalRedeemer = mkProposalRedeemer params.voteParameters
|
||||
|
||||
-- Off-chain code should do exactly like this: prepend new lock toStatus the list.
|
||||
updatedLocks :: [ProposalLock]
|
||||
updatedLocks = mkNewLock params : existingLocks
|
||||
proposalValue =
|
||||
normalizeValue $
|
||||
pst
|
||||
<> minAda
|
||||
|
||||
---
|
||||
proposalBuidler :: b
|
||||
proposalBuidler =
|
||||
foldMap
|
||||
( \i ->
|
||||
mconcat
|
||||
[ input $
|
||||
mconcat
|
||||
[ script proposalValidatorHash
|
||||
, withValue proposalValue
|
||||
, withRedeemer proposalRedeemer
|
||||
, withInlineDatum proposalInputDatum
|
||||
, withRef $ mkProposalRef i
|
||||
]
|
||||
, output $
|
||||
mconcat
|
||||
[ script proposalValidatorHash
|
||||
, withValue proposalValue
|
||||
, withInlineDatum proposalOutputDatum
|
||||
]
|
||||
]
|
||||
)
|
||||
[1 .. numProposals']
|
||||
|
||||
stakeOutputDatum :: StakeDatum
|
||||
stakeOutputDatum =
|
||||
stakeInputDatum
|
||||
{ lockedBy = updatedLocks
|
||||
}
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
---
|
||||
sig = case params.transactionParameters.signedBy of
|
||||
Owner -> stakeOwner
|
||||
Delegatee -> delegatee
|
||||
Unknown -> unknownSig
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
validTimeRange =
|
||||
closedBoundedInterval
|
||||
((def :: ProposalTimingConfig).draftTime + 1)
|
||||
((def :: ProposalTimingConfig).votingTime - 1)
|
||||
|
||||
---
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
stakeValue =
|
||||
sortValue $
|
||||
sst
|
||||
<> Value.assetClassValue (untag governor.gtClassRef) params.voteCount
|
||||
<> minAda
|
||||
miscBuilder :: b
|
||||
miscBuilder =
|
||||
mconcat
|
||||
[ signedWith sig
|
||||
, timeRange validTimeRange
|
||||
]
|
||||
|
||||
signer =
|
||||
if params.voteAsDelegate
|
||||
then delegate
|
||||
else stakeOwner
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
builder :: b
|
||||
builder =
|
||||
mconcat
|
||||
[ txId "827598fb2d69a896bbd9e645bb14c307df907f422b39eecbe4d6329bc30b428c"
|
||||
, signedWith signer
|
||||
, timeRange validTimeRange
|
||||
, input $
|
||||
mconcat
|
||||
[ script proposalValidatorHash
|
||||
, withValue pst
|
||||
, withDatum proposalInputDatum
|
||||
, withRef proposalRef
|
||||
, withRedeemer $ mkProposalRedeemer params
|
||||
]
|
||||
, input $
|
||||
mconcat
|
||||
[ script stakeValidatorHash
|
||||
, withValue stakeValue
|
||||
, withDatum stakeInputDatum
|
||||
, withRef stakeRef
|
||||
]
|
||||
, output $
|
||||
mconcat
|
||||
[ script proposalValidatorHash
|
||||
, withValue pst
|
||||
, withDatum proposalOutputDatum
|
||||
]
|
||||
, output $
|
||||
mconcat
|
||||
[ script stakeValidatorHash
|
||||
, withValue stakeValue
|
||||
, withDatum stakeOutputDatum
|
||||
]
|
||||
[ stakeBuilder
|
||||
, proposalBuidler
|
||||
, miscBuilder
|
||||
]
|
||||
in builder
|
||||
|
||||
---
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
-- | Valida parameters that vote on the proposal.
|
||||
validVoteParameters :: Parameters
|
||||
validVoteParameters =
|
||||
Parameters
|
||||
{ voteFor = ResultTag 0
|
||||
, voteCount = 27
|
||||
, voteAsDelegate = False
|
||||
}
|
||||
|
||||
validVoteAsDelegateParameters :: Parameters
|
||||
validVoteAsDelegateParameters =
|
||||
validVoteParameters
|
||||
{ voteAsDelegate = True
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
{- | Create a test tree that runs the stake validator and proposal validator to
|
||||
test the voting functionalities.
|
||||
-}
|
||||
mkTestTree :: String -> Parameters -> Bool -> SpecificationTree
|
||||
mkTestTree name ps isValid = group name [proposal, stake]
|
||||
mkTestTree :: String -> ParameterBundle -> Validity -> SpecificationTree
|
||||
mkTestTree name ps val = group name $ catMaybes [proposal, stake]
|
||||
where
|
||||
spend = mkSpending vote ps
|
||||
|
||||
numProposals' = numProposals ps.proposalParameters.numProposals
|
||||
|
||||
proposal =
|
||||
testValidator
|
||||
isValid
|
||||
"proposal"
|
||||
agoraScripts.compiledProposalValidator
|
||||
proposalInputDatum
|
||||
(mkProposalRedeemer ps)
|
||||
(spend proposalRef)
|
||||
case ps.proposalParameters.numProposals of
|
||||
NoProposal -> Nothing
|
||||
_ ->
|
||||
Just $
|
||||
testValidator
|
||||
val.forProposalValidator
|
||||
"proposal"
|
||||
agoraScripts.compiledProposalValidator
|
||||
proposalInputDatum
|
||||
(mkProposalRedeemer ps.voteParameters)
|
||||
(spend $ mkProposalRef 1)
|
||||
|
||||
stake =
|
||||
let stakeInputDatum = mkStakeInputDatum ps
|
||||
in validatorSucceedsWith
|
||||
"stake"
|
||||
agoraScripts.compiledStakeValidator
|
||||
stakeInputDatum
|
||||
stakeRedeemer
|
||||
(spend stakeRef)
|
||||
case ps.stakeParameters.numStakes of
|
||||
0 -> error "At least one stake"
|
||||
_ ->
|
||||
let stakeRef = mkStakeRef numProposals' 1
|
||||
in Just $
|
||||
testValidator
|
||||
val.forStakeValidator
|
||||
"stake"
|
||||
agoraScripts.compiledStakeValidator
|
||||
(mkStakeInputDatum ps.stakeParameters.stakeInputParameters)
|
||||
(mkStakeRedeemer ps.stakeParameters.stakeOutputParameters)
|
||||
(spend stakeRef)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
-- TODO(Connor) Use optics
|
||||
|
||||
mkValidOwnerVoteBundle :: Integer -> ParameterBundle
|
||||
mkValidOwnerVoteBundle stakes =
|
||||
ParamerterBundle
|
||||
{ voteParameters =
|
||||
VoteParameters
|
||||
{ voteFor = ResultTag 0
|
||||
}
|
||||
, stakeParameters =
|
||||
StakeParameters
|
||||
{ numStakes = stakes
|
||||
, stakeInputParameters =
|
||||
StakeInputParameters
|
||||
{ perStakeGTs = 114514
|
||||
}
|
||||
, stakeOutputParameters =
|
||||
StakeOutputParameters
|
||||
{ burnStakes = False
|
||||
, dontAddNewLock = False
|
||||
, changeGTAmount = False
|
||||
, changeAdaAmount = False
|
||||
}
|
||||
}
|
||||
, proposalParameters =
|
||||
ProposalParameters
|
||||
{ wrongAddedVotes = False
|
||||
, numProposals = OneProposal
|
||||
}
|
||||
, transactionParameters =
|
||||
TransactionParameters
|
||||
{ signedBy = Owner
|
||||
}
|
||||
}
|
||||
|
||||
mkValidDelegateeVoteBundle :: Integer -> ParameterBundle
|
||||
mkValidDelegateeVoteBundle stakes =
|
||||
let template = mkValidOwnerVoteBundle stakes
|
||||
in template
|
||||
{ transactionParameters =
|
||||
template.transactionParameters
|
||||
{ signedBy = Delegatee
|
||||
}
|
||||
}
|
||||
|
||||
ownerVoteWithSignleStake :: ParameterBundle
|
||||
ownerVoteWithSignleStake = mkValidOwnerVoteBundle 1
|
||||
|
||||
transparentAssets :: ParameterBundle
|
||||
transparentAssets =
|
||||
ownerVoteWithSignleStake
|
||||
{ stakeParameters =
|
||||
ownerVoteWithSignleStake.stakeParameters
|
||||
{ stakeOutputParameters =
|
||||
ownerVoteWithSignleStake.stakeParameters.stakeOutputParameters
|
||||
{ changeAdaAmount = True
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
transactionNotAuthorized :: ParameterBundle
|
||||
transactionNotAuthorized =
|
||||
ownerVoteWithSignleStake
|
||||
{ transactionParameters =
|
||||
ownerVoteWithSignleStake.transactionParameters
|
||||
{ signedBy = Unknown
|
||||
}
|
||||
}
|
||||
|
||||
voteForNonexistentOutcome :: ParameterBundle
|
||||
voteForNonexistentOutcome =
|
||||
ownerVoteWithSignleStake
|
||||
{ voteParameters =
|
||||
ownerVoteWithSignleStake.voteParameters
|
||||
{ voteFor = ResultTag 1919810
|
||||
}
|
||||
}
|
||||
|
||||
noProposal :: ParameterBundle
|
||||
noProposal =
|
||||
ownerVoteWithSignleStake
|
||||
{ proposalParameters =
|
||||
ownerVoteWithSignleStake.proposalParameters
|
||||
{ numProposals = NoProposal
|
||||
}
|
||||
}
|
||||
|
||||
moreThanOneProposals :: ParameterBundle
|
||||
moreThanOneProposals =
|
||||
ownerVoteWithSignleStake
|
||||
{ proposalParameters =
|
||||
ownerVoteWithSignleStake.proposalParameters
|
||||
{ numProposals = MoreThanOneProposals
|
||||
}
|
||||
}
|
||||
|
||||
ownerVoteWithMultipleStakes :: ParameterBundle
|
||||
ownerVoteWithMultipleStakes = mkValidOwnerVoteBundle 5
|
||||
|
||||
invalidLocks :: ParameterBundle
|
||||
invalidLocks =
|
||||
ownerVoteWithMultipleStakes
|
||||
{ stakeParameters =
|
||||
ownerVoteWithMultipleStakes.stakeParameters
|
||||
{ stakeOutputParameters =
|
||||
ownerVoteWithMultipleStakes.stakeParameters.stakeOutputParameters
|
||||
{ dontAddNewLock = True
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
destroyStakes :: ParameterBundle
|
||||
destroyStakes =
|
||||
ownerVoteWithMultipleStakes
|
||||
{ stakeParameters =
|
||||
ownerVoteWithMultipleStakes.stakeParameters
|
||||
{ stakeOutputParameters =
|
||||
ownerVoteWithMultipleStakes.stakeParameters.stakeOutputParameters
|
||||
{ burnStakes = True
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
insufficientAmount :: ParameterBundle
|
||||
insufficientAmount =
|
||||
ownerVoteWithSignleStake
|
||||
{ stakeParameters =
|
||||
ownerVoteWithSignleStake.stakeParameters
|
||||
{ stakeInputParameters =
|
||||
ownerVoteWithSignleStake.stakeParameters.stakeInputParameters
|
||||
{ perStakeGTs = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
insufficientAmount1 :: ParameterBundle
|
||||
insufficientAmount1 =
|
||||
ownerVoteWithMultipleStakes
|
||||
{ stakeParameters =
|
||||
ownerVoteWithMultipleStakes.stakeParameters
|
||||
{ stakeInputParameters =
|
||||
ownerVoteWithMultipleStakes.stakeParameters.stakeInputParameters
|
||||
{ perStakeGTs = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -189,6 +189,7 @@ instance Default ProposalThresholds where
|
|||
ProposalThresholds
|
||||
{ execute = Tagged 1000
|
||||
, create = Tagged 1
|
||||
, toVoting = Tagged 100
|
||||
, vote = Tagged 100
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -138,7 +138,6 @@ stakeDepositWithdraw config =
|
|||
mconcat
|
||||
[ txId "0b2086cbf8b6900f8cb65e012de4516cb66b5cb08a9aaba12a8b88be"
|
||||
, signedWith signer
|
||||
, mint st
|
||||
, input $
|
||||
mconcat
|
||||
[ script stakeValidatorHash
|
||||
|
|
@ -147,7 +146,7 @@ stakeDepositWithdraw config =
|
|||
st
|
||||
<> Value.assetClassValue (untag governor.gtClassRef) (fromDiscrete stakeBefore.stakedAmount)
|
||||
)
|
||||
, withDatum stakeAfter
|
||||
, withDatum stakeBefore
|
||||
, withRef stakeRef
|
||||
]
|
||||
, output $
|
||||
|
|
|
|||
|
|
@ -10,8 +10,9 @@ module Spec.Proposal (specs) where
|
|||
import Sample.Proposal.Advance qualified as Advance
|
||||
import Sample.Proposal.Cosign qualified as Cosign
|
||||
import Sample.Proposal.Create qualified as Create
|
||||
import Sample.Proposal.UnlockStake qualified as UnlockStake
|
||||
import Sample.Proposal.Unlock qualified as Unlock
|
||||
import Sample.Proposal.Vote qualified as Vote
|
||||
|
||||
import Test.Specification (
|
||||
SpecificationTree,
|
||||
group,
|
||||
|
|
@ -52,8 +53,8 @@ specs =
|
|||
"invalid stake locks"
|
||||
Create.addInvalidLocksParameters
|
||||
True
|
||||
False
|
||||
True
|
||||
False
|
||||
, Create.mkTestTree
|
||||
"has reached maximum proposals limit"
|
||||
Create.exceedMaximumProposalsParameters
|
||||
|
|
@ -128,10 +129,62 @@ specs =
|
|||
"voting"
|
||||
[ group
|
||||
"legal"
|
||||
[ Vote.mkTestTree "ordinary" Vote.validVoteParameters True
|
||||
, Vote.mkTestTree "delegate" Vote.validVoteAsDelegateParameters True
|
||||
[ group "different number of stakes" $
|
||||
map
|
||||
( \s ->
|
||||
group
|
||||
(unwords [show s, "stakes"])
|
||||
[ Vote.mkTestTree
|
||||
"by owner"
|
||||
(Vote.mkValidOwnerVoteBundle s)
|
||||
(Vote.Validity True True)
|
||||
, Vote.mkTestTree
|
||||
"by delegatee"
|
||||
(Vote.mkValidDelegateeVoteBundle s)
|
||||
(Vote.Validity True True)
|
||||
]
|
||||
)
|
||||
[1, 3, 5, 7, 9]
|
||||
, Vote.mkTestTree
|
||||
"transparent non-GT tokens"
|
||||
Vote.transparentAssets
|
||||
(Vote.Validity True True)
|
||||
]
|
||||
, group
|
||||
"illegal"
|
||||
[ Vote.mkTestTree
|
||||
"vote for nonexistent outcome"
|
||||
Vote.voteForNonexistentOutcome
|
||||
(Vote.Validity False True)
|
||||
, Vote.mkTestTree
|
||||
"unauthorized tx"
|
||||
Vote.transactionNotAuthorized
|
||||
(Vote.Validity True False)
|
||||
, Vote.mkTestTree
|
||||
"no proposal"
|
||||
Vote.noProposal
|
||||
(Vote.Validity False False)
|
||||
, Vote.mkTestTree
|
||||
"more than one proposals"
|
||||
Vote.voteForNonexistentOutcome
|
||||
(Vote.Validity False True)
|
||||
, Vote.mkTestTree
|
||||
"locks not added"
|
||||
Vote.invalidLocks
|
||||
(Vote.Validity True False)
|
||||
, Vote.mkTestTree
|
||||
"attempt to burn stakes"
|
||||
Vote.destroyStakes
|
||||
(Vote.Validity True False)
|
||||
, Vote.mkTestTree
|
||||
"insufficient staked amount"
|
||||
Vote.insufficientAmount
|
||||
(Vote.Validity False True)
|
||||
, Vote.mkTestTree
|
||||
"insufficient staked amount"
|
||||
Vote.insufficientAmount1
|
||||
(Vote.Validity False True)
|
||||
]
|
||||
-- TODO: add negative test cases
|
||||
]
|
||||
, group
|
||||
"advancing"
|
||||
|
|
@ -278,103 +331,72 @@ specs =
|
|||
]
|
||||
]
|
||||
, group "unlocking" $
|
||||
let proposalCountCases = [1, 5, 10, 42]
|
||||
let stakeCountCases = [1, 3, 5, 7, 9, 11]
|
||||
|
||||
mkSubgroupName nProposals = unwords ["with", show nProposals, "proposals"]
|
||||
mkSubgroupName nStakes = unwords ["with", show nStakes, "stakes"]
|
||||
|
||||
mkLegalGroup nProposals =
|
||||
mkLegalGroup nStakes =
|
||||
group
|
||||
(mkSubgroupName nProposals)
|
||||
[ UnlockStake.mkTestTree
|
||||
(mkSubgroupName nStakes)
|
||||
[ Unlock.mkTestTree
|
||||
"voter: retract votes while voting"
|
||||
(UnlockStake.mkVoterRetractVotesWhileVotingParameters nProposals)
|
||||
True
|
||||
, UnlockStake.mkTestTree
|
||||
(Unlock.mkValidVoterRetractVotes nStakes)
|
||||
(Unlock.Validity True True)
|
||||
, Unlock.mkTestTree
|
||||
"voter: retract votes while voting by delegatee"
|
||||
(Unlock.mkValidDelegateeRetractVotes nStakes)
|
||||
(Unlock.Validity True True)
|
||||
, Unlock.mkTestTree
|
||||
"voter/creator: retract votes while voting"
|
||||
(UnlockStake.mkVoterCreatorRetractVotesWhileVotingParameters nProposals)
|
||||
True
|
||||
, UnlockStake.mkTestTree
|
||||
"creator: remove creator locks when finished"
|
||||
(UnlockStake.mkCreatorRemoveCreatorLocksWhenFinishedParameters nProposals)
|
||||
True
|
||||
, UnlockStake.mkTestTree
|
||||
"voter/creator: remove all locks when finished"
|
||||
(UnlockStake.mkVoterCreatorRemoveAllLocksWhenFinishedParameters nProposals)
|
||||
True
|
||||
, group "voter: unlock after voting" $
|
||||
map
|
||||
( \ps ->
|
||||
let name = show ps.proposalStatus
|
||||
in UnlockStake.mkTestTree name ps True
|
||||
)
|
||||
(UnlockStake.mkVoterUnlockStakeAfterVotingParameters nProposals)
|
||||
, UnlockStake.mkTestTree
|
||||
"voter/creator: remove vote locks when locked"
|
||||
(UnlockStake.mkVoterCreatorRemoveVoteLocksWhenLockedParameters nProposals)
|
||||
True
|
||||
(Unlock.mkValidVoterCreatorRetractVotes nStakes)
|
||||
(Unlock.Validity True True)
|
||||
, Unlock.mkTestTree
|
||||
"creator: remove creator lock after voting"
|
||||
(Unlock.mkValidCreatorRemoveLock nStakes)
|
||||
(Unlock.Validity True True)
|
||||
, Unlock.mkTestTree
|
||||
"Voter: remove lock after voting"
|
||||
(Unlock.mkValidVoterRemoveLockAfterVoting nStakes)
|
||||
(Unlock.Validity True True)
|
||||
]
|
||||
|
||||
mkIllegalGroup nProposals =
|
||||
mkIllegalGroup nStakes =
|
||||
group
|
||||
(mkSubgroupName nProposals)
|
||||
(mkSubgroupName nStakes)
|
||||
[ group "retract votes while not voting" $
|
||||
map
|
||||
( \ps ->
|
||||
let name =
|
||||
unwords
|
||||
[ "role:"
|
||||
, show ps.stakeRole
|
||||
, ","
|
||||
, "status:"
|
||||
, show ps.proposalStatus
|
||||
]
|
||||
in UnlockStake.mkTestTree name ps False
|
||||
( \c ->
|
||||
Unlock.mkTestTree
|
||||
"(negative test)"
|
||||
c
|
||||
(Unlock.Validity False True)
|
||||
)
|
||||
(UnlockStake.mkRetractVotesWhileNotVoting nProposals)
|
||||
, group "unlock an irrelevant stake" $
|
||||
map
|
||||
( \ps ->
|
||||
let name =
|
||||
unwords
|
||||
[ "status:"
|
||||
, show ps.proposalStatus
|
||||
, "retract votes:"
|
||||
, show ps.retractVotes
|
||||
]
|
||||
in UnlockStake.mkTestTree name ps False
|
||||
)
|
||||
(UnlockStake.mkUnockIrrelevantStakeParameters nProposals)
|
||||
(Unlock.mkRetractVotesWhileNotVoting nStakes)
|
||||
, group "remove creator too early" $
|
||||
map
|
||||
( \ps ->
|
||||
let name =
|
||||
unwords
|
||||
["status:", show ps.proposalStatus]
|
||||
in UnlockStake.mkTestTree name ps False
|
||||
( \c ->
|
||||
Unlock.mkTestTree
|
||||
"(negative test)"
|
||||
c
|
||||
(Unlock.Validity True False)
|
||||
)
|
||||
(UnlockStake.mkRemoveCreatorLockBeforeFinishedParameters nProposals)
|
||||
, UnlockStake.mkTestTree
|
||||
(Unlock.mkRemoveCreatorLockBeforeFinished nStakes)
|
||||
, Unlock.mkTestTree
|
||||
"unlock an irrelevant stake"
|
||||
(Unlock.mkUnockIrrelevantStakes nStakes)
|
||||
(Unlock.Validity False True)
|
||||
, Unlock.mkTestTree
|
||||
"creator: retract votes"
|
||||
(UnlockStake.mkRetractVotesWithCreatorStakeParamaters nProposals)
|
||||
False
|
||||
, group "alter output stake datum" $
|
||||
map
|
||||
( \ps ->
|
||||
let name =
|
||||
unwords
|
||||
[ "role:"
|
||||
, show ps.stakeRole
|
||||
, ","
|
||||
, "status:"
|
||||
, show ps.proposalStatus
|
||||
]
|
||||
in UnlockStake.mkTestTree name ps False
|
||||
)
|
||||
(UnlockStake.mkAlterStakeParameters nProposals)
|
||||
(Unlock.mkCreatorRetractVotes nStakes)
|
||||
(Unlock.Validity False True)
|
||||
, Unlock.mkTestTree
|
||||
"change output stake value"
|
||||
(Unlock.mkChangeOutputStakeValue nStakes)
|
||||
(Unlock.Validity True False)
|
||||
]
|
||||
|
||||
legalGroup = group "legal" $ map mkLegalGroup proposalCountCases
|
||||
illegalGroup = group "illegal" $ map mkIllegalGroup proposalCountCases
|
||||
legalGroup = group "legal" $ map mkLegalGroup stakeCountCases
|
||||
illegalGroup = group "illegal" $ map mkIllegalGroup stakeCountCases
|
||||
in [legalGroup, illegalGroup]
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ library agora-specs
|
|||
Sample.Proposal.Cosign
|
||||
Sample.Proposal.Create
|
||||
Sample.Proposal.Shared
|
||||
Sample.Proposal.UnlockStake
|
||||
Sample.Proposal.Unlock
|
||||
Sample.Proposal.Vote
|
||||
Sample.Shared
|
||||
Sample.Stake
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ import Agora.Scripts (
|
|||
stakeSTSymbol,
|
||||
)
|
||||
import Agora.Stake (
|
||||
PProposalLock (..),
|
||||
PStakeDatum (..),
|
||||
pnumCreatedProposals,
|
||||
)
|
||||
|
|
@ -469,31 +468,6 @@ governorValidator as =
|
|||
#&& proposalOutputDatumF.timingConfig #== governorInputDatumF.proposalTimings
|
||||
]
|
||||
|
||||
-- Check the output stake has been properly updated.
|
||||
|
||||
let stakeOutputDatum =
|
||||
passertPJust # "Output stake should be presented"
|
||||
#$ pfindJust
|
||||
# getStakeDatum
|
||||
# pfromData txInfoF.outputs
|
||||
|
||||
stakeOutputLocks =
|
||||
pfromData $ pfield @"lockedBy" # stakeOutputDatum
|
||||
|
||||
-- The stake should be locked by the newly created proposal.
|
||||
newLock =
|
||||
mkRecordConstr
|
||||
PCreated
|
||||
( #created .= governorInputDatumF.nextProposalId
|
||||
)
|
||||
|
||||
-- Append new locks to existing locks
|
||||
expectedProposalLocks =
|
||||
pcons # pdata newLock # stakeInputDatumF.lockedBy
|
||||
|
||||
pguardC "Stake output locks correct" $
|
||||
plistEquals # stakeOutputLocks # expectedProposalLocks
|
||||
|
||||
pure $ popaque $ pconstant ()
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ import Data.Bifunctor (Bifunctor (bimap))
|
|||
import Data.Map.Strict qualified as StrictMap
|
||||
import Data.Traversable (for)
|
||||
import Plutarch.Api.V1 (KeyGuarantees (Sorted), PMap)
|
||||
import Plutarch.Num (PNum)
|
||||
import Plutarch.SafeMoney (PDiscrete)
|
||||
import PlutusTx qualified
|
||||
import PlutusTx.AssocMap qualified as AssocMap
|
||||
|
||||
|
|
@ -74,3 +76,6 @@ instance
|
|||
isSorted [] = True
|
||||
isSorted [_] = True
|
||||
isSorted (x : y : xs) = x < y && isSorted (y : xs)
|
||||
|
||||
-- | @since 1.0.0
|
||||
deriving anyclass instance PNum (PDiscrete tag)
|
||||
|
|
|
|||
|
|
@ -67,8 +67,7 @@ import Plutarch.DataRepr (
|
|||
),
|
||||
PDataFields,
|
||||
)
|
||||
import Plutarch.Extra.Comonad (pextract)
|
||||
import Plutarch.Extra.Field (pletAllC)
|
||||
import Plutarch.Extra.Field (pletAll)
|
||||
import Plutarch.Extra.Function (pbuiltinUncurry)
|
||||
import Plutarch.Extra.IsData (
|
||||
DerivePConstantViaDataList (DerivePConstantViaDataList),
|
||||
|
|
@ -81,14 +80,14 @@ import Plutarch.Extra.IsData (
|
|||
import "liqwid-plutarch-extra" Plutarch.Extra.List (pfindJust)
|
||||
import Plutarch.Extra.Map qualified as PM
|
||||
import Plutarch.Extra.Maybe (pfromJust)
|
||||
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pguardC, pletC, pmatchC)
|
||||
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pguardC, pletC)
|
||||
import Plutarch.Lift (
|
||||
DerivePConstantViaNewtype (DerivePConstantViaNewtype),
|
||||
PConstantDecl,
|
||||
PUnsafeLiftDecl (type PLifted),
|
||||
)
|
||||
import Plutarch.Orphans ()
|
||||
import Plutarch.SafeMoney (PDiscrete (PDiscrete))
|
||||
import Plutarch.SafeMoney (PDiscrete)
|
||||
import PlutusLedgerApi.V2 (Credential, DatumHash, ScriptHash, ValidatorHash)
|
||||
import PlutusTx qualified
|
||||
|
||||
|
|
@ -222,7 +221,7 @@ data ProposalStatus
|
|||
This data is stored centrally (in the 'Agora.Governor.Governor') and copied over
|
||||
to 'Proposal's when they are created.
|
||||
|
||||
@since 0.1.0
|
||||
@since 1.0.0
|
||||
-}
|
||||
data ProposalThresholds = ProposalThresholds
|
||||
{ execute :: Tagged GTTag Integer
|
||||
|
|
@ -232,9 +231,10 @@ data ProposalThresholds = ProposalThresholds
|
|||
--
|
||||
-- It is recommended this be a high enough amount, in order to prevent DOS from bad
|
||||
-- actors.
|
||||
, toVoting :: Tagged GTTag Integer
|
||||
-- ^ How much GT required to to move into 'Locked'.
|
||||
, vote :: Tagged GTTag Integer
|
||||
-- ^ How much GT required to allow voting to happen.
|
||||
-- (i.e. to move into 'VotingReady')
|
||||
-- ^ How much GT required to vote on a outcome.
|
||||
}
|
||||
deriving stock
|
||||
( -- | @since 0.1.0
|
||||
|
|
@ -553,7 +553,7 @@ deriving via (DerivePConstantViaEnum ProposalStatus PProposalStatus) instance (P
|
|||
|
||||
{- | Plutarch-level version of 'ProposalThresholds'.
|
||||
|
||||
@since 0.1.0
|
||||
@since 1.0.0
|
||||
-}
|
||||
newtype PProposalThresholds (s :: S) = PProposalThresholds
|
||||
{ getProposalThresholds ::
|
||||
|
|
@ -562,6 +562,7 @@ newtype PProposalThresholds (s :: S) = PProposalThresholds
|
|||
( PDataRecord
|
||||
'[ "execute" ':= PDiscrete GTTag
|
||||
, "create" ':= PDiscrete GTTag
|
||||
, "toVoting" ':= PDiscrete GTTag
|
||||
, "vote" ':= PDiscrete GTTag
|
||||
]
|
||||
)
|
||||
|
|
@ -617,6 +618,8 @@ newtype PProposalVotes (s :: S)
|
|||
PlutusType
|
||||
, -- | @since 0.1.0
|
||||
PIsData
|
||||
, -- | @since 1.0.0
|
||||
PShow
|
||||
)
|
||||
|
||||
-- | @since 0.2.0
|
||||
|
|
@ -949,23 +952,18 @@ pneutralOption = phoistAcyclic $
|
|||
-}
|
||||
pisProposalThresholdsValid :: forall (s :: S). Term s (PProposalThresholds :--> PBool)
|
||||
pisProposalThresholdsValid = phoistAcyclic $
|
||||
plam $ \thresholds -> unTermCont $ do
|
||||
thresholdsF <- pletAllC thresholds
|
||||
|
||||
PDiscrete execute' <- pmatchC thresholdsF.execute
|
||||
PDiscrete draft' <- pmatchC thresholdsF.create
|
||||
PDiscrete vote' <- pmatchC thresholdsF.vote
|
||||
|
||||
execute <- pletC $ pextract # execute'
|
||||
draft <- pletC $ pextract # draft'
|
||||
vote <- pletC $ pextract # vote'
|
||||
|
||||
pure $
|
||||
plam $
|
||||
flip pletAll $ \thresholdsF ->
|
||||
foldr1
|
||||
(#&&)
|
||||
[ ptraceIfFalse "Execute threshold is less than or equal to 0" $ 0 #<= execute
|
||||
, ptraceIfFalse "Draft threshold is less than or equal to 0" $ 0 #<= draft
|
||||
, ptraceIfFalse "Vote threshold is less than or equal to 0" $ 0 #<= vote
|
||||
[ ptraceIfFalse "Execute threshold is less than or equal to 0" $
|
||||
0 #<= pfromData thresholdsF.execute
|
||||
, ptraceIfFalse "Create threshold is less than or equal to 0" $
|
||||
0 #<= pfromData thresholdsF.create
|
||||
, ptraceIfFalse "toVoting threshold is less than or equal to 0" $
|
||||
0 #<= pfromData thresholdsF.toVoting
|
||||
, ptraceIfFalse "Vote threshold is less than or equal to 0" $
|
||||
0 #<= pfromData thresholdsF.vote
|
||||
]
|
||||
|
||||
{- | Retract votes given the option and the amount of votes.
|
||||
|
|
|
|||
|
|
@ -29,17 +29,16 @@ import Agora.Proposal.Time (
|
|||
)
|
||||
import Agora.Scripts (AgoraScripts, governorSTSymbol, proposalSTSymbol, stakeSTAssetClass)
|
||||
import Agora.Stake (
|
||||
PProposalLock (PVoted),
|
||||
PStakeDatum,
|
||||
pextractVoteOption,
|
||||
pgetStakeRole,
|
||||
pisCreator,
|
||||
pisIrrelevant,
|
||||
pisPureCreator,
|
||||
pisVoter,
|
||||
)
|
||||
import Agora.Utils (
|
||||
plistEqualsBy,
|
||||
pmapMaybe,
|
||||
)
|
||||
import Plutarch.Api.V1 (PCredential)
|
||||
import Plutarch.Api.V1.AssocMap (plookup)
|
||||
|
|
@ -53,7 +52,7 @@ import Plutarch.Api.V2 (
|
|||
PValidator,
|
||||
)
|
||||
import Plutarch.Extra.AssetClass (passetClass, passetClassValueOf)
|
||||
import Plutarch.Extra.Category (PCategory (pidentity), PSemigroupoid ((#>>>)))
|
||||
import Plutarch.Extra.Category (PCategory (pidentity))
|
||||
import Plutarch.Extra.Comonad (pextract)
|
||||
import Plutarch.Extra.Field (pletAll, pletAllC)
|
||||
import "liqwid-plutarch-extra" Plutarch.Extra.List (pfindJust)
|
||||
|
|
@ -73,6 +72,7 @@ import Plutarch.Extra.ScriptContext (
|
|||
pisTokenSpent,
|
||||
ptryFromOutputDatum,
|
||||
)
|
||||
import Plutarch.Extra.Sum (PSum (PSum))
|
||||
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (
|
||||
pguardC,
|
||||
pletC,
|
||||
|
|
@ -80,6 +80,7 @@ import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (
|
|||
pmatchC,
|
||||
ptryFromC,
|
||||
)
|
||||
import Plutarch.Extra.Traversable (pfoldMap)
|
||||
import Plutarch.Extra.Value (psymbolValueOf)
|
||||
import Plutarch.SafeMoney (PDiscrete (PDiscrete))
|
||||
import Plutarch.Unsafe (punsafeCoerce)
|
||||
|
|
@ -154,13 +155,9 @@ data PWitnessMultipleStakeContext (s :: S) = PWitnessMultipleStakeContext
|
|||
instance DerivePlutusType PWitnessMultipleStakeContext where
|
||||
type DPTStrat _ = PlutusTypeScott
|
||||
|
||||
{- | Validation context for redeemers which need to modify a single stake.
|
||||
|
||||
@since 1.0.0
|
||||
-}
|
||||
data PSpendSingleStakeContext (s :: S) = PSpendSingleStakeContext
|
||||
{ inputStake :: Term s PStakeDatum
|
||||
, outputStake :: Term s PStakeDatum
|
||||
-- | @since 1.0.0
|
||||
newtype PStakeInputsContext (s :: S) = PStakeInputsContext
|
||||
{ inputStakes :: Term s (PList PStakeDatum)
|
||||
}
|
||||
deriving stock
|
||||
( -- | @since 1.0.0
|
||||
|
|
@ -172,8 +169,8 @@ data PSpendSingleStakeContext (s :: S) = PSpendSingleStakeContext
|
|||
)
|
||||
|
||||
-- | @since 1.0.0
|
||||
instance DerivePlutusType PSpendSingleStakeContext where
|
||||
type DPTStrat _ = PlutusTypeScott
|
||||
instance DerivePlutusType PStakeInputsContext where
|
||||
type DPTStrat _ = PlutusTypeNewtype
|
||||
|
||||
{- | The validator for Proposals.
|
||||
|
||||
|
|
@ -186,6 +183,7 @@ instance DerivePlutusType PSpendSingleStakeContext where
|
|||
When voting and unlocking, the proposal must witness a state transition
|
||||
occuring in the relevant Stake. This transition must place a lock on
|
||||
the stake that is tagged with the right 'Agora.Proposal.ResultTag', and 'Agora.Proposal.ProposalId'.
|
||||
Note that only one proposal per transaction is supported.
|
||||
|
||||
=== Periods
|
||||
|
||||
|
|
@ -256,66 +254,59 @@ proposalValidator as maximumCosigners =
|
|||
-- * has an PST
|
||||
-- * has the same proposal id as the proposal input
|
||||
--
|
||||
-- We match the proposal id here so that we can support multiple
|
||||
-- proposal inputs in one thansaction.
|
||||
-- We can handle only one proposal under current design.
|
||||
proposalOutputDatum <-
|
||||
pletC $
|
||||
passertPJust
|
||||
# "Own output should be present"
|
||||
#$ pfindJust
|
||||
# plam
|
||||
( flip pletAll $ \outputF ->
|
||||
let pstSymbol = pconstant $ proposalSTSymbol as
|
||||
passertPJust # "proposal input should present"
|
||||
#$ pfindJust
|
||||
# plam
|
||||
( flip pletAll $ \outputF ->
|
||||
let pstSymbol = pconstant $ proposalSTSymbol as
|
||||
|
||||
isProposalUTxO =
|
||||
foldl1
|
||||
(#&&)
|
||||
[ ptraceIfFalse "Own by proposal validator" $
|
||||
outputF.address #== proposalInputF.address
|
||||
, ptraceIfFalse "Has proposal ST" $
|
||||
psymbolValueOf # pstSymbol # outputF.value #== 1
|
||||
]
|
||||
isProposalUTxO =
|
||||
foldl1
|
||||
(#&&)
|
||||
[ ptraceIfFalse "Own by proposal validator" $
|
||||
outputF.address #== proposalInputF.address
|
||||
, ptraceIfFalse "Has proposal ST" $
|
||||
psymbolValueOf # pstSymbol # outputF.value #== 1
|
||||
]
|
||||
|
||||
handleProposalUTxO = unTermCont $ do
|
||||
-- Using inline datum to avoid O(n^2) lookup.
|
||||
datum <-
|
||||
pletC $
|
||||
pfromData $
|
||||
ptrace "Resolve proposal datum" $
|
||||
pfromOutputDatum @(PAsData PProposalDatum)
|
||||
# outputF.datum
|
||||
# txInfoF.datums
|
||||
|
||||
pure $
|
||||
pif
|
||||
( pfield @"proposalId" # pto datum
|
||||
#== proposalInputDatumF.proposalId
|
||||
)
|
||||
(pjust # datum)
|
||||
pnothing
|
||||
in pif
|
||||
isProposalUTxO
|
||||
handleProposalUTxO
|
||||
pnothing
|
||||
)
|
||||
# pfromData txInfoF.outputs
|
||||
handleProposalUTxO =
|
||||
-- Using inline datum to avoid O(n^2) lookup.
|
||||
pfromData $
|
||||
ptrace "Resolve proposal datum" $
|
||||
pfromOutputDatum @(PAsData PProposalDatum)
|
||||
# outputF.datum
|
||||
# txInfoF.datums
|
||||
in pif
|
||||
isProposalUTxO
|
||||
(pjust # handleProposalUTxO)
|
||||
pnothing
|
||||
)
|
||||
# pfromData txInfoF.outputs
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
let AssetClass (sstSymbol, sstName) = stakeSTAssetClass as
|
||||
|
||||
-- Handle stake input/output.
|
||||
sstAssetClass <-
|
||||
pletC $
|
||||
passetClass
|
||||
# pconstant sstSymbol
|
||||
# pconstant sstName
|
||||
|
||||
-- Handle stake inputs/outputs.
|
||||
|
||||
-- Reslove stake datum if the given UTxO is a stake UTxO.
|
||||
getStakeDatum :: Term _ (PTxOut :--> PMaybe PStakeDatum) <-
|
||||
pletC $
|
||||
plam $
|
||||
flip (pletFields @'["value", "datum"]) $ \txOutF ->
|
||||
let AssetClass (stakeSym, _) = stakeSTAssetClass as
|
||||
|
||||
isStakeUTxO =
|
||||
let isStakeUTxO =
|
||||
-- A stake UTxO is a UTxO that carries SST.
|
||||
psymbolValueOf
|
||||
# pconstant stakeSym
|
||||
passetClassValueOf
|
||||
# txOutF.value
|
||||
# sstAssetClass
|
||||
#== 1
|
||||
|
||||
stake =
|
||||
|
|
@ -328,6 +319,26 @@ proposalValidator as maximumCosigners =
|
|||
# txInfoF.datums
|
||||
in pif isStakeUTxO (pjust # stake) pnothing
|
||||
|
||||
spendStakes' :: Term _ ((PStakeInputsContext :--> PUnit) :--> PUnit) <-
|
||||
pletC $
|
||||
plam $
|
||||
let stakeInputs =
|
||||
pmapMaybe
|
||||
# plam ((getStakeDatum #) . (pfield @"resolved" #))
|
||||
# pfromData txInfoF.inputs
|
||||
|
||||
ctx = pcon $ PStakeInputsContext stakeInputs
|
||||
in (# ctx)
|
||||
|
||||
let spendStakes ::
|
||||
( PStakeInputsContext _ ->
|
||||
TermCont _ ()
|
||||
) ->
|
||||
Term _ POpaque
|
||||
spendStakes c = popaque $
|
||||
spendStakes' #$ plam $ \sctx ->
|
||||
unTermCont $ pmatchC sctx >>= c >> pure (pconstant ())
|
||||
|
||||
-- Witness stakes in reference inputs.
|
||||
witnessStakes' ::
|
||||
Term
|
||||
|
|
@ -388,34 +399,6 @@ proposalValidator as maximumCosigners =
|
|||
witnessStakes' #$ plam $ \sctxF ->
|
||||
unTermCont $ pmatchC sctxF >>= c >> pure (pconstant ())
|
||||
|
||||
-- We don't need to explicitly ensure that there's only one stake in the
|
||||
-- inputs here - the stake validator will do it for us.
|
||||
spendSingleStake' ::
|
||||
Term
|
||||
s
|
||||
((PSpendSingleStakeContext :--> PUnit) :--> PUnit) <-
|
||||
pletC $
|
||||
let stakeInput =
|
||||
passertPJust # "Stake input should present" #$ pfindJust
|
||||
# ((pfield @"resolved" @_ @PTxInInfo) #>>> getStakeDatum)
|
||||
# txInfoF.inputs
|
||||
|
||||
stakeOutput =
|
||||
passertPJust # "Stake output should present"
|
||||
#$ pfindJust # getStakeDatum # txInfoF.outputs
|
||||
|
||||
ctx = pcon $ PSpendSingleStakeContext stakeInput stakeOutput
|
||||
in plam (# ctx)
|
||||
|
||||
let spendSingleStake ::
|
||||
( PSpendSingleStakeContext _ ->
|
||||
TermCont _ ()
|
||||
) ->
|
||||
Term _ POpaque
|
||||
spendSingleStake c = popaque $
|
||||
spendSingleStake' #$ plam $ \sctx ->
|
||||
unTermCont $ pmatchC sctx >>= c >> pure (pconstant ())
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
proposalRedeemer <- fst <$> ptryFromC @PProposalRedeemer redeemer
|
||||
|
|
@ -474,8 +457,28 @@ proposalValidator as maximumCosigners =
|
|||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
PVote r -> spendSingleStake $ \sctxF -> do
|
||||
stakeInF <- pletAllC $ pto sctxF.inputStake
|
||||
PVote r -> spendStakes $ \sctxF -> do
|
||||
totalStakeAmount <-
|
||||
pletC $
|
||||
pto $
|
||||
pfoldMap
|
||||
# plam
|
||||
( \stake -> unTermCont $ do
|
||||
stakeF <- pletFieldsC @'["stakedAmount", "lockedBy"] stake
|
||||
|
||||
pguardC "Same stake shouldn't vote on the same proposal twice" $
|
||||
pnot
|
||||
#$ pisVoter
|
||||
#$ pgetStakeRole
|
||||
# proposalInputDatumF.proposalId
|
||||
# stakeF.lockedBy
|
||||
|
||||
pure $ pcon $ PSum $ pfromData stakeF.stakedAmount
|
||||
)
|
||||
# sctxF.inputStakes
|
||||
|
||||
pguardC "Exceed minimum amount" $
|
||||
thresholdsF.vote #< totalStakeAmount
|
||||
|
||||
pguardC "Input proposal must be in VotingReady state" $
|
||||
currentStatus #== pconstant VotingReady
|
||||
|
|
@ -494,10 +497,6 @@ proposalValidator as maximumCosigners =
|
|||
pguardC "Vote option should be valid" $
|
||||
pisJust #$ plookup # voteFor # voteMap
|
||||
|
||||
-- Ensure that no lock with the current proposal id has been put on the stake.
|
||||
pguardC "Same stake shouldn't vote on the same proposal twice" $
|
||||
pnot #$ pisVoter #$ pgetStakeRole # proposalInputDatumF.proposalId # stakeInF.lockedBy
|
||||
|
||||
let -- The amount of new votes should be the 'stakedAmount'.
|
||||
-- Update the vote counter of the proposal, and leave other stuff as is.
|
||||
expectedNewVotes =
|
||||
|
|
@ -506,7 +505,7 @@ proposalValidator as maximumCosigners =
|
|||
pupdate
|
||||
# plam
|
||||
( \votes -> unTermCont $ do
|
||||
PDiscrete v <- pmatchC stakeInF.stakedAmount
|
||||
PDiscrete v <- pmatchC totalStakeAmount
|
||||
pure $ pcon $ PJust $ votes + (pextract # v)
|
||||
)
|
||||
# voteFor
|
||||
|
|
@ -528,76 +527,68 @@ proposalValidator as maximumCosigners =
|
|||
pguardC "Output proposal should be valid" $
|
||||
proposalOutputDatum #== expectedProposalOut
|
||||
|
||||
-- We validate the output stake datum here as well: We need the vote option
|
||||
-- to create a valid 'ProposalLock', however the vote option is encoded
|
||||
-- in the proposal redeemer, which is invisible for the stake validator.
|
||||
|
||||
let newProposalLock =
|
||||
mkRecordConstr
|
||||
PVoted
|
||||
( #votedOn .= proposalInputDatumF.proposalId
|
||||
.& #votedFor .= pdata voteFor
|
||||
)
|
||||
|
||||
-- Prepend the new lock to existing locks
|
||||
expectedProposalLocks =
|
||||
pcons
|
||||
# pdata newProposalLock
|
||||
# pfromData stakeInF.lockedBy
|
||||
|
||||
pguardC "Output stake should be locked by the proposal" $
|
||||
pfield @"lockedBy" # sctxF.outputStake #== expectedProposalLocks
|
||||
-- Note that the output stake locks validation now happens in the
|
||||
-- stake validator.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
PUnlock _ -> spendSingleStake $ \sctxF -> do
|
||||
stakeInF <- pletAllC $ pto sctxF.inputStake
|
||||
PUnlock _ -> spendStakes $ \sctxF -> do
|
||||
let expectedVotes =
|
||||
pfoldl
|
||||
# plam
|
||||
( \votes stake -> unTermCont $ do
|
||||
stakeF <-
|
||||
pletFieldsC
|
||||
@'["stakedAmount", "lockedBy"]
|
||||
stake
|
||||
|
||||
stakeRole <- pletC $ pgetStakeRole # proposalInputDatumF.proposalId # stakeInF.lockedBy
|
||||
stakeRole <-
|
||||
pletC $
|
||||
pgetStakeRole
|
||||
# proposalInputDatumF.proposalId
|
||||
# stakeF.lockedBy
|
||||
|
||||
pguardC "Stake input should be relevant" $
|
||||
pnot #$ pisIrrelevant # stakeRole
|
||||
pguardC "Stake input should be relevant" $
|
||||
pnot #$ pisIrrelevant # stakeRole
|
||||
|
||||
retractCount <-
|
||||
pletC $
|
||||
pmatch stakeInF.stakedAmount $ \(PDiscrete v) -> pextract # v
|
||||
let canRetractVotes =
|
||||
pnot #$ pisPureCreator # stakeRole
|
||||
|
||||
-- The votes can only change when the proposal still allows voting.
|
||||
let shouldUpdateVotes =
|
||||
voteCount =
|
||||
pextract
|
||||
#$ pto
|
||||
$ pfromData stakeF.stakedAmount
|
||||
|
||||
newVotes =
|
||||
pretractVotes
|
||||
# (pextractVoteOption # stakeRole)
|
||||
# voteCount
|
||||
# votes
|
||||
|
||||
pure $ pif canRetractVotes newVotes votes
|
||||
)
|
||||
# proposalInputDatumF.votes
|
||||
# sctxF.inputStakes
|
||||
|
||||
currentTime' =
|
||||
passertPJust
|
||||
# "Should be able to get current time"
|
||||
# currentTime
|
||||
|
||||
inVotingPeriod =
|
||||
isVotingPeriod # proposalInputDatumF.timingConfig
|
||||
# proposalInputDatumF.startingTime
|
||||
# currentTime'
|
||||
|
||||
-- The votes can only change when the proposal still allows voting.
|
||||
shouldUpdateVotes =
|
||||
currentStatus #== pconstant VotingReady
|
||||
#&& pnot # (pisPureCreator # stakeRole)
|
||||
|
||||
allowRemovingCreatorLock =
|
||||
currentStatus #== pconstant Finished
|
||||
|
||||
isCreator = pisCreator # stakeRole
|
||||
|
||||
-- If the stake has been used for creating the proposal,
|
||||
-- the creator lock can only be removed when the proposal
|
||||
-- is finished.
|
||||
--
|
||||
-- In other cases, all the locks related to this
|
||||
-- proposal should be removed.
|
||||
validateOutputLocks = plam $ \locks ->
|
||||
plet
|
||||
( pgetStakeRole # proposalInputDatumF.proposalId # locks
|
||||
)
|
||||
$ \newStakeRole ->
|
||||
pif
|
||||
(isCreator #&& pnot # allowRemovingCreatorLock)
|
||||
(pisPureCreator # newStakeRole)
|
||||
(pisIrrelevant # newStakeRole)
|
||||
#&& inVotingPeriod
|
||||
|
||||
pguardC "Proposal output correct" $
|
||||
pif
|
||||
shouldUpdateVotes
|
||||
( let -- Remove votes and leave other parts of the proposal as it.
|
||||
expectedVotes =
|
||||
pretractVotes
|
||||
# (pextractVoteOption # stakeRole)
|
||||
# retractCount
|
||||
# proposalInputDatumF.votes
|
||||
|
||||
expectedProposalOut =
|
||||
mkRecordConstr
|
||||
PProposalDatum
|
||||
|
|
@ -618,12 +609,6 @@ proposalValidator as maximumCosigners =
|
|||
proposalOutputDatum #== proposalInputDatum
|
||||
)
|
||||
|
||||
-- At last, we ensure that all locks belong to this proposal will be removed.
|
||||
stakeOutputLocks <- pletC $ pfield @"lockedBy" # pto sctxF.outputStake
|
||||
|
||||
pguardC "All relevant locks removed from the stake" $
|
||||
validateOutputLocks # stakeOutputLocks
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
PAdvanceProposal _ -> unTermCont $ do
|
||||
|
|
@ -674,7 +659,7 @@ proposalValidator as maximumCosigners =
|
|||
pmatchC notTooLate >>= \case
|
||||
PTrue -> do
|
||||
pguardC "More cosigns than minimum amount" $
|
||||
punsafeCoerce (pfromData thresholdsF.vote) #< sctxF.totalAmount
|
||||
punsafeCoerce (pfromData thresholdsF.toVoting) #< sctxF.totalAmount
|
||||
|
||||
pguardC "All new cosigners are witnessed by their Stake datums" $
|
||||
plistEqualsBy
|
||||
|
|
|
|||
|
|
@ -21,8 +21,7 @@ module Agora.Stake (
|
|||
PStakeRole (..),
|
||||
|
||||
-- * Validation context
|
||||
PStakeInputContext (..),
|
||||
PStakeOutputContext (..),
|
||||
PSignedBy (..),
|
||||
PSigContext (..),
|
||||
PStakeRedeemerContext (..),
|
||||
PStakeRedeemerHandlerContext (..),
|
||||
|
|
@ -43,14 +42,19 @@ module Agora.Stake (
|
|||
runStakeRedeemerHandler,
|
||||
) where
|
||||
|
||||
import Agora.Proposal (PProposalId, PProposalRedeemer, PResultTag, ProposalId, ResultTag)
|
||||
import Agora.Proposal (
|
||||
PProposalId,
|
||||
PProposalRedeemer,
|
||||
PProposalStatus,
|
||||
PResultTag,
|
||||
ProposalId,
|
||||
ResultTag,
|
||||
)
|
||||
import Agora.SafeMoney (GTTag)
|
||||
import Data.Tagged (Tagged)
|
||||
import Generics.SOP qualified as SOP
|
||||
import Plutarch.Api.V1 (KeyGuarantees (Sorted), PCredential)
|
||||
import Plutarch.Api.V1.Value (PValue)
|
||||
import Plutarch.Api.V1 (PCredential)
|
||||
import Plutarch.Api.V2 (
|
||||
AmountGuarantees (Positive),
|
||||
PMaybeData,
|
||||
PTxInfo,
|
||||
)
|
||||
|
|
@ -58,7 +62,6 @@ import Plutarch.DataRepr (
|
|||
DerivePConstantViaData (DerivePConstantViaData),
|
||||
PDataFields,
|
||||
)
|
||||
import Plutarch.Extra.AssetClass (PAssetClass)
|
||||
import Plutarch.Extra.Field (pletAll)
|
||||
import Plutarch.Extra.IsData (
|
||||
DerivePConstantViaDataList (DerivePConstantViaDataList),
|
||||
|
|
@ -250,6 +253,8 @@ newtype PStakeDatum (s :: S) = PStakeDatum
|
|||
PEq
|
||||
, -- | @since 1.0.0
|
||||
PDataFields
|
||||
, -- | @since 1.0.0
|
||||
PShow
|
||||
)
|
||||
|
||||
instance DerivePlutusType PStakeDatum where
|
||||
|
|
@ -429,61 +434,11 @@ instance DerivePlutusType PStakeRole where
|
|||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
{- | Represent the stake being spent.
|
||||
|
||||
@since 1.0.0
|
||||
-}
|
||||
data PStakeInputContext (s :: S) = PStakeInput
|
||||
{ ownInputDatum :: Term s PStakeDatum
|
||||
-- ^ The stake datum of said stake.
|
||||
, ownInputValue :: Term s (PValue 'Sorted 'Positive)
|
||||
-- ^ The value carried by the stake UTxO.
|
||||
}
|
||||
deriving stock
|
||||
( -- | @since 1.0.0
|
||||
Generic
|
||||
)
|
||||
deriving anyclass
|
||||
( -- | @since 1.0.0
|
||||
PlutusType
|
||||
)
|
||||
|
||||
-- | @since 1.0.0
|
||||
instance DerivePlutusType PStakeInputContext where
|
||||
type DPTStrat _ = PlutusTypeScott
|
||||
|
||||
{- | Where the stake will go?
|
||||
|
||||
@since 1.0.0
|
||||
-}
|
||||
data PStakeOutputContext (s :: S)
|
||||
= -- | The output stake is owned by the stake validator.
|
||||
PStakeOutput
|
||||
{ ownOutputDatum :: Term s PStakeDatum
|
||||
-- ^ The stake datum of the output stake.
|
||||
, ownOutputValue :: Term s (PValue 'Sorted 'Positive)
|
||||
-- ^ The value carried by the stake output UTxO.
|
||||
}
|
||||
| -- | The stake is burnt in the transaction.
|
||||
PStakeBurnt
|
||||
deriving stock
|
||||
( -- | @since 1.0.0
|
||||
Generic
|
||||
)
|
||||
deriving anyclass
|
||||
( -- | @since 1.0.0
|
||||
PlutusType
|
||||
)
|
||||
|
||||
-- | @since 1.0.0
|
||||
instance DerivePlutusType PStakeOutputContext where
|
||||
type DPTStrat _ = PlutusTypeScott
|
||||
|
||||
{- | Who authorizes the transaction?
|
||||
|
||||
@since 1.0.0
|
||||
-}
|
||||
data PSigContext (s :: S)
|
||||
data PSignedBy (s :: S)
|
||||
= -- | The stake owner authorized the transaction.
|
||||
PSignedByOwner
|
||||
| -- | The delegate authorized the transaction.
|
||||
|
|
@ -499,6 +454,28 @@ data PSigContext (s :: S)
|
|||
PlutusType
|
||||
)
|
||||
|
||||
-- | @since 1.0.0
|
||||
instance DerivePlutusType PSignedBy where
|
||||
type DPTStrat _ = PlutusTypeScott
|
||||
|
||||
{- | The signature context.
|
||||
|
||||
@since 1.0.0
|
||||
-}
|
||||
data PSigContext (s :: S) = PSigContext
|
||||
{ owner :: Term s PCredential
|
||||
, delegatee :: Term s (PMaybeData (PAsData PCredential))
|
||||
, signedBy :: Term s PSignedBy
|
||||
}
|
||||
deriving stock
|
||||
( -- | @since 1.0.0
|
||||
Generic
|
||||
)
|
||||
deriving anyclass
|
||||
( -- | @since 1.0.0
|
||||
PlutusType
|
||||
)
|
||||
|
||||
-- | @since 1.0.0
|
||||
instance DerivePlutusType PSigContext where
|
||||
type DPTStrat _ = PlutusTypeScott
|
||||
|
|
@ -532,9 +509,13 @@ instance DerivePlutusType PStakeRedeemerContext where
|
|||
-}
|
||||
data PProposalContext (s :: S)
|
||||
= -- | A proposal is spent.
|
||||
PWithProposalRedeemer (Term s PProposalRedeemer)
|
||||
PSpendProposal
|
||||
(Term s PProposalId)
|
||||
(Term s PProposalStatus)
|
||||
(Term s PProposalRedeemer)
|
||||
| -- | A new proposal is created.
|
||||
PNewProposal
|
||||
(Term s PProposalId)
|
||||
| -- | No proposal is spent or created.
|
||||
PNoProposal
|
||||
deriving stock
|
||||
|
|
@ -555,12 +536,11 @@ instance DerivePlutusType PProposalContext where
|
|||
@1.0.0
|
||||
-}
|
||||
data PStakeRedeemerHandlerContext (s :: S) = PStakeRedeemerHandlerContext
|
||||
{ stakeInput :: Term s PStakeInputContext
|
||||
, stakeOutput :: Term s PStakeOutputContext
|
||||
{ stakeInputDatums :: Term s (PList PStakeDatum)
|
||||
, stakeOutputDatums :: Term s (PList PStakeDatum)
|
||||
, redeemerContext :: Term s PStakeRedeemerContext
|
||||
, sigContext :: Term s PSigContext
|
||||
, proposalContext :: Term s PProposalContext
|
||||
, gtAssetClass :: Term s PAssetClass
|
||||
, extraTxContext :: Term s PTxInfo
|
||||
}
|
||||
deriving stock
|
||||
|
|
@ -585,13 +565,19 @@ instance DerivePlutusType PStakeRedeemerHandlerContext where
|
|||
-}
|
||||
type PStakeRedeemerHandler = PStakeRedeemerHandlerContext :--> PUnit
|
||||
|
||||
{- | Newtype wrapper around @'ClosedTerm' 'PStakeRedeemerHandler'@ to allow type inference to work.
|
||||
{- | Newtype wrapper around @'ClosedTerm' 'PStakeRedeemerHandler'@ to allow type
|
||||
inference to work.
|
||||
|
||||
@since 1.0.0
|
||||
-}
|
||||
newtype PStakeRedeemerHandlerTerm = PStakeRedeemerHandlerTerm (ClosedTerm PStakeRedeemerHandler)
|
||||
newtype PStakeRedeemerHandlerTerm
|
||||
= PStakeRedeemerHandlerTerm
|
||||
(ClosedTerm PStakeRedeemerHandler)
|
||||
|
||||
runStakeRedeemerHandler :: PStakeRedeemerHandlerTerm -> ClosedTerm PStakeRedeemerHandler
|
||||
-- | @since 1.0.0
|
||||
runStakeRedeemerHandler ::
|
||||
PStakeRedeemerHandlerTerm ->
|
||||
ClosedTerm PStakeRedeemerHandler
|
||||
runStakeRedeemerHandler (PStakeRedeemerHandlerTerm t) = t
|
||||
|
||||
{- | A collection of stake redeemer handlers for each stake redeemers.
|
||||
|
|
@ -666,7 +652,14 @@ pisIrrelevant = phoistAcyclic $
|
|||
|
||||
@since 0.2.0
|
||||
-}
|
||||
pgetStakeRole :: forall (s :: S). Term s (PProposalId :--> PBuiltinList (PAsData PProposalLock) :--> PStakeRole)
|
||||
pgetStakeRole ::
|
||||
forall (s :: S).
|
||||
Term
|
||||
s
|
||||
( PProposalId
|
||||
:--> PBuiltinList (PAsData PProposalLock)
|
||||
:--> PStakeRole
|
||||
)
|
||||
pgetStakeRole = phoistAcyclic $
|
||||
plam $ \pid locks ->
|
||||
pfoldl
|
||||
|
|
@ -688,7 +681,14 @@ pgetStakeRole = phoistAcyclic $
|
|||
# pcon PIrrelevant
|
||||
# locks
|
||||
where
|
||||
pcombineStakeRole :: forall (s :: S). Term s (PStakeRole :--> PStakeRole :--> PStakeRole)
|
||||
pcombineStakeRole ::
|
||||
forall (s :: S).
|
||||
Term
|
||||
s
|
||||
( PStakeRole
|
||||
:--> PStakeRole
|
||||
:--> PStakeRole
|
||||
)
|
||||
pcombineStakeRole = phoistAcyclic $
|
||||
plam $ \x y ->
|
||||
let cannotCombine = ptraceError "duplicate roles"
|
||||
|
|
|
|||
|
|
@ -14,138 +14,247 @@ module Agora.Stake.Redeemers (
|
|||
pdepositWithdraw,
|
||||
) where
|
||||
|
||||
import Agora.Proposal (PProposalRedeemer (PUnlock, PVote))
|
||||
import Agora.Proposal (
|
||||
PProposalId,
|
||||
PProposalRedeemer (PUnlock, PVote),
|
||||
ProposalStatus (Finished),
|
||||
)
|
||||
import Agora.Stake (
|
||||
PProposalContext (PNewProposal, PWithProposalRedeemer),
|
||||
PSigContext (PSignedByOwner, PUnknownSig),
|
||||
PProposalContext (
|
||||
PNewProposal,
|
||||
PNoProposal,
|
||||
PSpendProposal
|
||||
),
|
||||
PProposalLock (PCreated, PVoted),
|
||||
PSigContext (owner, signedBy),
|
||||
PSignedBy (
|
||||
PSignedByDelegate,
|
||||
PSignedByOwner,
|
||||
PUnknownSig
|
||||
),
|
||||
PStakeDatum (PStakeDatum),
|
||||
PStakeInputContext (PStakeInput),
|
||||
PStakeOutputContext (PStakeBurnt, PStakeOutput),
|
||||
PStakeRedeemerContext (PDepositWithdrawDelta, PNoMetadata, PSetDelegateTo),
|
||||
PStakeRedeemerContext (
|
||||
PDepositWithdrawDelta,
|
||||
PNoMetadata,
|
||||
PSetDelegateTo
|
||||
),
|
||||
PStakeRedeemerHandler,
|
||||
PStakeRedeemerHandlerContext (..),
|
||||
PStakeRedeemerHandlerContext (
|
||||
proposalContext,
|
||||
redeemerContext,
|
||||
sigContext,
|
||||
stakeInputDatums,
|
||||
stakeOutputDatums
|
||||
),
|
||||
pstakeLocked,
|
||||
)
|
||||
import Agora.Utils (pdeleteBy, pfromSingleton, pisSingleton)
|
||||
import Plutarch.Api.V1.Address (PCredential)
|
||||
import Plutarch.Api.V1.Value (AmountGuarantees (Positive), PValue)
|
||||
import Plutarch.Api.V2 (PMaybeData)
|
||||
import Plutarch.Extra.Field (pletAllC)
|
||||
import Plutarch.Extra.Field (pletAll, pletAllC)
|
||||
import Plutarch.Extra.Maybe (pdjust, pdnothing, pmaybeData)
|
||||
import Plutarch.Extra.Record (mkRecordConstr, (.&), (.=))
|
||||
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pguardC, pletC, pmatchC)
|
||||
import Plutarch.Extra.Value (pgeqByClass, pgeqByClass')
|
||||
import Plutarch.Numeric.Additive (AdditiveMonoid (zero), AdditiveSemigroup ((+)))
|
||||
import Plutarch.SafeMoney (pdiscreteValue)
|
||||
import PlutusLedgerApi.V1.Value (AssetClass (..))
|
||||
import Prelude hiding (Num ((+)))
|
||||
|
||||
-- | Return true if stake input and output carries the same value.
|
||||
pownOutputValueUnchanged ::
|
||||
-- | A wrapper which ensures that no proposal is presented in the transaction.
|
||||
pwithoutProposal ::
|
||||
forall (s :: S).
|
||||
Term s (PStakeRedeemerHandlerContext :--> PBool)
|
||||
pownOutputValueUnchanged = phoistAcyclic $
|
||||
plam $
|
||||
flip pmatch $ \ctxF -> unTermCont $ do
|
||||
PStakeInput _ inVal <- pmatchC ctxF.stakeInput
|
||||
PStakeOutput _ outVal <- pmatchC ctxF.stakeOutput
|
||||
Term
|
||||
s
|
||||
(PStakeRedeemerHandler :--> PStakeRedeemerHandler)
|
||||
pwithoutProposal = phoistAcyclic $
|
||||
plam $ \f ctx -> pmatch ctx $ \ctxF ->
|
||||
pif
|
||||
( pmatch ctxF.proposalContext $ \case
|
||||
PNoProposal -> pconstant True
|
||||
_ -> pconstant False
|
||||
)
|
||||
(f # ctx)
|
||||
(ptraceError "No proposal is allowed")
|
||||
|
||||
pure $ inVal #== outVal
|
||||
{- | Validate stake outputs given a function that converts an input stake datum
|
||||
to an ouput stake datum. / O(n^2) /.
|
||||
-}
|
||||
pbatchUpdateInputs ::
|
||||
forall (s :: S).
|
||||
Term
|
||||
s
|
||||
( (PStakeDatum :--> PStakeDatum :--> PBool)
|
||||
:--> PStakeRedeemerHandlerContext
|
||||
:--> PBool
|
||||
)
|
||||
pbatchUpdateInputs = phoistAcyclic $
|
||||
plam $ \f -> flip pmatch $ \ctxF ->
|
||||
pnull #$ pfoldr
|
||||
# (pdeleteBy # f)
|
||||
# ctxF.stakeOutputDatums
|
||||
# ctxF.stakeInputDatums
|
||||
|
||||
-- | Extract the 'PSigContext.signedBy' field from 'PStakeRedeemerHandlerContext'.
|
||||
pgetSignedBy ::
|
||||
forall (s :: S).
|
||||
Term
|
||||
s
|
||||
(PStakeRedeemerHandlerContext :--> PSignedBy)
|
||||
pgetSignedBy = phoistAcyclic $
|
||||
plam $ \ctx -> unTermCont $ do
|
||||
ctxF <- pmatchC ctx
|
||||
sctxF <- pmatchC ctxF.sigContext
|
||||
pure sctxF.signedBy
|
||||
|
||||
-- | Return true if the tx is authorized by either the owner or the delegatee.
|
||||
pisSignedBy ::
|
||||
forall (s :: S).
|
||||
Term
|
||||
s
|
||||
(PBool :--> PStakeRedeemerHandlerContext :--> PBool)
|
||||
pisSignedBy = phoistAcyclic $
|
||||
plam $ \byDelegate ctx ->
|
||||
pmatch (pgetSignedBy # ctx) $ \case
|
||||
PSignedByOwner -> pconstant True
|
||||
PSignedByDelegate -> byDelegate
|
||||
PUnknownSig -> pconstant False
|
||||
|
||||
-- | Return true if only the @lockedBy@ field of the stake datum is updated.
|
||||
ponlyLocksUpdated ::
|
||||
forall (s :: S).
|
||||
Term s (PStakeRedeemerHandlerContext :--> PBool)
|
||||
Term
|
||||
s
|
||||
( ( PBuiltinList (PAsData PProposalLock)
|
||||
:--> PBuiltinList (PAsData PProposalLock)
|
||||
)
|
||||
:--> PStakeRedeemerHandlerContext
|
||||
:--> PBool
|
||||
)
|
||||
ponlyLocksUpdated = phoistAcyclic $
|
||||
plam $
|
||||
flip pmatch $ \ctxF -> unTermCont $ do
|
||||
PStakeInput inDat _ <- pmatchC ctxF.stakeInput
|
||||
PStakeOutput outDat _ <- pmatchC ctxF.stakeOutput
|
||||
plam $ \f ->
|
||||
pbatchUpdateInputs #$ plam $ \i o ->
|
||||
pletAll i $ \iF ->
|
||||
let newLocks = f # pfromData iF.lockedBy
|
||||
|
||||
inDatF <- pletAllC inDat
|
||||
|
||||
let onlyLocksUpdated =
|
||||
let templateStakeDatum =
|
||||
mkRecordConstr
|
||||
PStakeDatum
|
||||
( #stakedAmount .= inDatF.stakedAmount
|
||||
.& #owner .= inDatF.owner
|
||||
.& #delegatedTo .= inDatF.delegatedTo
|
||||
.& #lockedBy .= pfield @"lockedBy" # outDat
|
||||
)
|
||||
in outDat #== templateStakeDatum
|
||||
|
||||
pure onlyLocksUpdated
|
||||
|
||||
-- | Return true if the transaction is signed by the owner of the stake.
|
||||
psignedByOwner ::
|
||||
forall (s :: S).
|
||||
Term s (PStakeRedeemerHandlerContext :--> PBool)
|
||||
psignedByOwner = phoistAcyclic $
|
||||
plam $
|
||||
flip pmatch $ \ctxF -> pmatch ctxF.sigContext $ \case
|
||||
PSignedByOwner -> pconstant True
|
||||
_ -> pconstant False
|
||||
expected =
|
||||
mkRecordConstr
|
||||
PStakeDatum
|
||||
( #stakedAmount .= iF.stakedAmount
|
||||
.& #owner .= iF.owner
|
||||
.& #delegatedTo .= iF.delegatedTo
|
||||
.& #lockedBy .= pdata newLocks
|
||||
)
|
||||
in expected #== o
|
||||
|
||||
-- | Validation logic shared between 'ppermitVote' and 'retractVote'.
|
||||
pvoteHelper ::
|
||||
forall (s :: S).
|
||||
Term
|
||||
s
|
||||
( (PProposalContext :--> PBool)
|
||||
( ( PStakeRedeemerHandlerContext
|
||||
:--> PBuiltinList (PAsData PProposalLock)
|
||||
:--> PBuiltinList (PAsData PProposalLock)
|
||||
)
|
||||
:--> PStakeRedeemerHandler
|
||||
)
|
||||
pvoteHelper = phoistAcyclic $
|
||||
plam $ \valProposalCtx ctx -> unTermCont $ do
|
||||
ctxF <- pmatchC ctx
|
||||
|
||||
pguardC "Owner or delegate signs this transaction" $
|
||||
pmatch ctxF.sigContext $ \case
|
||||
PUnknownSig -> pconstant False
|
||||
_ -> pconstant True
|
||||
pisSignedBy # pconstant True # ctx
|
||||
|
||||
-- This puts trust into the Proposal. The Proposal must necessarily check
|
||||
-- that this is not abused.
|
||||
|
||||
pguardC "Proposal ST spent" $
|
||||
valProposalCtx # ctxF.proposalContext
|
||||
|
||||
pguardC "A UTXO must exist with the correct output" $
|
||||
let valueCorrect = pownOutputValueUnchanged # ctx
|
||||
outputDatumCorrect = ponlyLocksUpdated # ctx
|
||||
in foldl1
|
||||
(#&&)
|
||||
[ ptraceIfFalse "valueCorrect" valueCorrect
|
||||
, ptraceIfFalse "datumCorrect" outputDatumCorrect
|
||||
]
|
||||
pguardC "Correct outputs" $
|
||||
ponlyLocksUpdated # (valProposalCtx # ctx) # ctx
|
||||
|
||||
pure $ pconstant ()
|
||||
|
||||
-- | Add new lock the the existing list of locked.
|
||||
paddNewLock ::
|
||||
forall (s :: S).
|
||||
Term
|
||||
s
|
||||
( PProposalLock
|
||||
:--> PBuiltinList (PAsData PProposalLock)
|
||||
:--> PBuiltinList (PAsData PProposalLock)
|
||||
)
|
||||
paddNewLock = phoistAcyclic $
|
||||
plam $
|
||||
-- Prepend the lock.
|
||||
\newLock -> pcons # pdata newLock
|
||||
|
||||
{- | Default implementation of 'Agora.Stake.PermitVote'.
|
||||
|
||||
@since 1.0.0
|
||||
-}
|
||||
ppermitVote :: forall (s :: S). Term s PStakeRedeemerHandler
|
||||
ppermitVote = pvoteHelper #$ phoistAcyclic $
|
||||
plam $
|
||||
flip pmatch $ \case
|
||||
PWithProposalRedeemer r -> pmatch r $ \case
|
||||
PVote _ -> pconstant True
|
||||
_ -> ptrace "Expected Vote" $ pconstant False
|
||||
PNewProposal -> pconstant True
|
||||
_ -> pconstant False
|
||||
ppermitVote = phoistAcyclic $
|
||||
pvoteHelper #$ phoistAcyclic $
|
||||
plam $ \ctx -> unTermCont $ do
|
||||
ctxF <- pmatchC ctx
|
||||
|
||||
let withOnlyOneStakeInput =
|
||||
plam $ \lock -> unTermCont $ do
|
||||
pguardC "Only one stake input allowed" $
|
||||
pisSingleton # ctxF.stakeInputDatums
|
||||
|
||||
pure lock
|
||||
|
||||
pure $
|
||||
paddNewLock #$ pmatch ctxF.proposalContext $ \case
|
||||
PSpendProposal pid _ r -> pmatch r $ \case
|
||||
PVote ((pfromData . (pfield @"resultTag" #)) -> voteFor) ->
|
||||
mkRecordConstr
|
||||
PVoted
|
||||
( #votedOn .= pdata pid
|
||||
.& #votedFor .= pdata voteFor
|
||||
)
|
||||
_ -> ptraceError "Expected Vote"
|
||||
PNewProposal pid ->
|
||||
withOnlyOneStakeInput
|
||||
#$ mkRecordConstr
|
||||
PCreated
|
||||
( #created .= pdata pid
|
||||
)
|
||||
_ -> ptraceError "Expected proposal"
|
||||
|
||||
{- | Remove stake locks with the proposal id given the list of existing locks.
|
||||
The first parameter controls whether to revmove creator locks or not.
|
||||
-}
|
||||
premoveLocks ::
|
||||
forall (s :: S).
|
||||
Term
|
||||
s
|
||||
( PProposalId
|
||||
:--> PBool
|
||||
:--> PBuiltinList (PAsData PProposalLock)
|
||||
:--> PBuiltinList (PAsData PProposalLock)
|
||||
)
|
||||
premoveLocks = phoistAcyclic $
|
||||
plam $ \pid rc ->
|
||||
pfilter
|
||||
# plam
|
||||
( \(pfromData -> l) -> pnot #$ pmatch l $ \case
|
||||
PCreated ((pfield @"created" #) -> pid') -> rc #&& pid' #== pid
|
||||
PVoted ((pfield @"votedOn" #) -> pid') -> pid' #== pid
|
||||
)
|
||||
|
||||
{- | Default implementation of 'Agora.Stake.RetractVotes'.
|
||||
|
||||
@since 1.0.0
|
||||
-}
|
||||
pretractVote :: forall (s :: S). Term s PStakeRedeemerHandler
|
||||
pretractVote = pvoteHelper #$ phoistAcyclic $
|
||||
plam $
|
||||
flip pmatch $ \case
|
||||
PWithProposalRedeemer r -> pmatch r $ \case
|
||||
PUnlock _ -> pconstant True
|
||||
_ -> ptrace "Expected Unlock" $ pconstant False
|
||||
_ -> pconstant False
|
||||
pretractVote = phoistAcyclic $
|
||||
pvoteHelper #$ phoistAcyclic $
|
||||
plam $
|
||||
flip pmatch $ \ctxF ->
|
||||
pmatch ctxF.proposalContext $ \case
|
||||
PSpendProposal pid s r -> pmatch r $ \case
|
||||
PUnlock _ ->
|
||||
let allowRemovingCreatorLock =
|
||||
s #== pconstant Finished
|
||||
in premoveLocks # pid # allowRemovingCreatorLock
|
||||
_ -> ptraceError "Expected unlock"
|
||||
_ -> ptraceError "Expected spending proposal"
|
||||
|
||||
-- | Validation logic shared by 'pdelegateTo' and 'pclearDelegate'.
|
||||
pdelegateHelper ::
|
||||
|
|
@ -156,40 +265,35 @@ pdelegateHelper ::
|
|||
:--> PStakeRedeemerHandler
|
||||
)
|
||||
pdelegateHelper = phoistAcyclic $
|
||||
plam $ \f ctx -> unTermCont $ do
|
||||
plam $ \f -> pwithoutProposal #$ plam $ \ctx -> unTermCont $ do
|
||||
ctxF <- pmatchC ctx
|
||||
sigCtxF <- pmatchC ctxF.sigContext
|
||||
|
||||
pguardC "Owner signs this transaction" $ psignedByOwner # ctx
|
||||
pguardC "Owner signs this transaction" $
|
||||
pisSignedBy # pconstant False # ctx
|
||||
|
||||
PStakeInput inpDat _ <- pmatchC ctxF.stakeInput
|
||||
PStakeOutput outDat _ <- pmatchC ctxF.stakeOutput
|
||||
|
||||
inpDatF <- pletAllC inpDat
|
||||
|
||||
let maybePkh = f # ctxF.redeemerContext
|
||||
let newDelegate = f # ctxF.redeemerContext
|
||||
|
||||
pguardC "Cannot delegate to the owner" $
|
||||
pmaybeData
|
||||
# pcon PTrue
|
||||
# plam (\pkh -> pnot #$ inpDatF.owner #== pkh)
|
||||
# maybePkh
|
||||
# plam (\pkh -> pnot #$ sigCtxF.owner #== pfromData pkh)
|
||||
# newDelegate
|
||||
|
||||
pguardC "A UTXO must exist with the correct output" $
|
||||
let correctOutputDatum =
|
||||
outDat
|
||||
#== mkRecordConstr
|
||||
pguardC "Correct outputs" $
|
||||
pbatchUpdateInputs
|
||||
# plam
|
||||
( \i o -> pletAll i $ \iF ->
|
||||
mkRecordConstr
|
||||
PStakeDatum
|
||||
( #stakedAmount .= inpDatF.stakedAmount
|
||||
.& #owner .= inpDatF.owner
|
||||
.& #delegatedTo .= pdata maybePkh
|
||||
.& #lockedBy .= inpDatF.lockedBy
|
||||
( #stakedAmount .= iF.stakedAmount
|
||||
.& #owner .= iF.owner
|
||||
.& #delegatedTo .= pdata newDelegate
|
||||
.& #lockedBy .= iF.lockedBy
|
||||
)
|
||||
valueCorrect = pownOutputValueUnchanged # ctx
|
||||
in foldl1
|
||||
(#&&)
|
||||
[ ptraceIfFalse "valueCorrect" valueCorrect
|
||||
, ptraceIfFalse "datumCorrect" correctOutputDatum
|
||||
]
|
||||
#== o
|
||||
)
|
||||
# ctx
|
||||
|
||||
pure $ pconstant ()
|
||||
|
||||
|
|
@ -221,16 +325,14 @@ pclearDelegate = pdelegateHelper #$ phoistAcyclic $
|
|||
-}
|
||||
pdestroy :: forall (s :: S). Term s PStakeRedeemerHandler
|
||||
pdestroy = phoistAcyclic $
|
||||
plam $ \ctx -> unTermCont $ do
|
||||
pwithoutProposal #$ plam $ \ctx -> unTermCont $ do
|
||||
ctxF <- pmatchC ctx
|
||||
|
||||
PStakeInput inpDat _ <- pmatchC ctxF.stakeInput
|
||||
PStakeBurnt <- pmatchC ctxF.stakeOutput
|
||||
|
||||
pguardC "Owner signs this transaction" $
|
||||
psignedByOwner # ctx
|
||||
pisSignedBy # pconstant False # ctx
|
||||
|
||||
pguardC "Stake unlocked" $ pnot #$ pstakeLocked # inpDat
|
||||
pguardC "Stake unlocked" $
|
||||
pnot #$ pany # pstakeLocked # ctxF.stakeInputDatums
|
||||
|
||||
pure $ pconstant ()
|
||||
|
||||
|
|
@ -240,64 +342,46 @@ pdestroy = phoistAcyclic $
|
|||
-}
|
||||
pdepositWithdraw :: forall (s :: S). Term s PStakeRedeemerHandler
|
||||
pdepositWithdraw = phoistAcyclic $
|
||||
plam $ \ctx -> unTermCont $ do
|
||||
pwithoutProposal #$ plam $ \ctx -> unTermCont $ do
|
||||
ctxF <- pmatchC ctx
|
||||
|
||||
PStakeInput inpDat inpVal <- pmatchC ctxF.stakeInput
|
||||
PStakeOutput outDat outVal <- pmatchC ctxF.stakeOutput
|
||||
pguardC "Owner signs this transaction" $
|
||||
pisSignedBy # pconstant False # ctx
|
||||
|
||||
pguardC "Stake unlocked" $ pnot #$ pstakeLocked # inpDat
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
pguardC "Owner signs this transaction" $ psignedByOwner # ctx
|
||||
stakeInputDatum <-
|
||||
pletC $
|
||||
ptrace "Single stake input" $
|
||||
pfromSingleton # ctxF.stakeInputDatums
|
||||
stakeInputDatumF <- pletAllC stakeInputDatum
|
||||
|
||||
pguardC
|
||||
"A UTXO must exist with the correct output"
|
||||
$ unTermCont $ do
|
||||
inpDatF <- pletAllC inpDat
|
||||
PDepositWithdrawDelta delta <- pmatchC ctxF.redeemerContext
|
||||
let stakeOutputDatum =
|
||||
ptrace "Single stake output" $
|
||||
pfromSingleton # ctxF.stakeOutputDatums
|
||||
|
||||
let oldStakedAmount = pfromData $ inpDatF.stakedAmount
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
newStakedAmount <- pletC $ oldStakedAmount + delta
|
||||
pguardC "Stake unlocked" $
|
||||
pnot #$ pstakeLocked # stakeInputDatum
|
||||
|
||||
pguardC "New staked amount should be greater than or equal to 0" $
|
||||
zero #<= newStakedAmount
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
let expectedDatum =
|
||||
mkRecordConstr
|
||||
PStakeDatum
|
||||
( #stakedAmount .= pdata newStakedAmount
|
||||
.& #owner .= inpDatF.owner
|
||||
.& #delegatedTo .= inpDatF.delegatedTo
|
||||
.& #lockedBy .= inpDatF.lockedBy
|
||||
)
|
||||
datumCorrect = outDat #== expectedDatum
|
||||
PDepositWithdrawDelta delta <- pmatchC ctxF.redeemerContext
|
||||
|
||||
let valueDelta :: Term _ (PValue _ 'Positive)
|
||||
valueDelta = pdiscreteValue # ctxF.gtAssetClass # delta
|
||||
newStakedAmount <- pletC $ stakeInputDatumF.stakedAmount + delta
|
||||
|
||||
expectedValue =
|
||||
inpVal <> valueDelta
|
||||
pguardC "Non-negative staked amount" $ zero #<= newStakedAmount
|
||||
|
||||
gtAssetClassF <- pletAllC ctxF.gtAssetClass
|
||||
let expectedDatum =
|
||||
mkRecordConstr
|
||||
PStakeDatum
|
||||
( #stakedAmount .= pdata newStakedAmount
|
||||
.& #owner .= stakeInputDatumF.owner
|
||||
.& #delegatedTo .= stakeInputDatumF.delegatedTo
|
||||
.& #lockedBy .= stakeInputDatumF.lockedBy
|
||||
)
|
||||
|
||||
pguardC "Valid output datum" $ expectedDatum #== stakeOutputDatum
|
||||
|
||||
let valueCorrect =
|
||||
foldr1
|
||||
(#&&)
|
||||
[ pgeqByClass' (AssetClass ("", ""))
|
||||
# outVal
|
||||
# expectedValue
|
||||
, pgeqByClass
|
||||
# gtAssetClassF.currencySymbol
|
||||
# gtAssetClassF.tokenName
|
||||
# outVal
|
||||
# expectedValue
|
||||
]
|
||||
--
|
||||
pure $
|
||||
foldl1
|
||||
(#&&)
|
||||
[ ptraceIfFalse "valueCorrect" valueCorrect
|
||||
, ptraceIfFalse "datumCorrect" datumCorrect
|
||||
]
|
||||
pure $ pconstant ()
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ module Agora.Stake.Scripts (
|
|||
) where
|
||||
|
||||
import Agora.Credential (authorizationContext, pauthorizedBy)
|
||||
import Agora.Proposal (PProposalRedeemer)
|
||||
import Agora.Proposal (PProposalDatum, PProposalRedeemer)
|
||||
import Agora.SafeMoney (GTTag)
|
||||
import Agora.Scripts (
|
||||
AgoraScripts,
|
||||
|
|
@ -23,17 +23,23 @@ import Agora.Stake (
|
|||
PProposalContext (
|
||||
PNewProposal,
|
||||
PNoProposal,
|
||||
PWithProposalRedeemer
|
||||
PSpendProposal
|
||||
),
|
||||
PSigContext (
|
||||
PSigContext (PSigContext),
|
||||
PSignedBy (
|
||||
PSignedByDelegate,
|
||||
PSignedByOwner,
|
||||
PUnknownSig
|
||||
),
|
||||
PStakeDatum,
|
||||
PStakeInputContext (PStakeInput),
|
||||
PStakeOutputContext (PStakeBurnt, PStakeOutput),
|
||||
PStakeRedeemer (PClearDelegate, PDelegateTo, PDepositWithdraw, PDestroy, PPermitVote, PRetractVotes),
|
||||
PStakeRedeemer (
|
||||
PClearDelegate,
|
||||
PDelegateTo,
|
||||
PDepositWithdraw,
|
||||
PDestroy,
|
||||
PPermitVote,
|
||||
PRetractVotes
|
||||
),
|
||||
PStakeRedeemerContext (
|
||||
PDepositWithdrawDelta,
|
||||
PNoMetadata,
|
||||
|
|
@ -55,18 +61,21 @@ import Agora.Stake.Redeemers (
|
|||
ppermitVote,
|
||||
pretractVote,
|
||||
)
|
||||
import Agora.Utils (pmapMaybe)
|
||||
import Data.Tagged (Tagged (Tagged))
|
||||
import Plutarch.Api.V1 (
|
||||
KeyGuarantees (Sorted),
|
||||
PCredential (PPubKeyCredential, PScriptCredential),
|
||||
PTokenName,
|
||||
)
|
||||
import Plutarch.Api.V1.AssocMap (plookup)
|
||||
import Plutarch.Api.V1.Value (PValue)
|
||||
import Plutarch.Api.V2 (
|
||||
AmountGuarantees,
|
||||
PMintingPolicy,
|
||||
PScriptPurpose (PMinting, PSpending),
|
||||
PTxInInfo,
|
||||
PTxInfo,
|
||||
PTxOutRef,
|
||||
PTxOut,
|
||||
PValidator,
|
||||
)
|
||||
import Plutarch.Extra.AssetClass (
|
||||
|
|
@ -74,13 +83,13 @@ import Plutarch.Extra.AssetClass (
|
|||
passetClassValueOf,
|
||||
pvalueOf,
|
||||
)
|
||||
import Plutarch.Extra.Bind (PBind ((#>>=)))
|
||||
import Plutarch.Extra.Field (pletAllC)
|
||||
import Plutarch.Extra.Field (pletAll)
|
||||
import Plutarch.Extra.Functor (PFunctor (pfmap))
|
||||
import "liqwid-plutarch-extra" Plutarch.Extra.List (pfindJust)
|
||||
import Plutarch.Extra.Maybe (
|
||||
passertPJust,
|
||||
pfromMaybe,
|
||||
pjust,
|
||||
pmaybe,
|
||||
pmaybeData,
|
||||
pnothing,
|
||||
)
|
||||
|
|
@ -100,6 +109,7 @@ import Plutarch.Extra.Value (
|
|||
psymbolValueOf,
|
||||
)
|
||||
import Plutarch.SafeMoney (
|
||||
pvalueDiscrete,
|
||||
pvalueDiscrete',
|
||||
)
|
||||
import Plutarch.Unsafe (punsafeCoerce)
|
||||
|
|
@ -235,8 +245,14 @@ mkStakeValidator
|
|||
impl
|
||||
as
|
||||
(Tagged (AssetClass (gtSym, gtTn))) =
|
||||
plam $ \datum redeemer ctx -> unTermCont $ do
|
||||
gtAssetClass <- pletC $ passetClass # pconstant gtSym # pconstant gtTn
|
||||
plam $ \_datum redeemer ctx -> unTermCont $ do
|
||||
let sstValueOf ::
|
||||
( forall (ag :: AmountGuarantees) (s :: S).
|
||||
Term s (PValue 'Sorted ag :--> PInteger)
|
||||
)
|
||||
sstValueOf =
|
||||
phoistAcyclic $
|
||||
psymbolValueOf # pconstant (stakeSTSymbol as)
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -257,118 +273,152 @@ mkStakeValidator
|
|||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
-- Assemble the stake input context.
|
||||
|
||||
stakeInputDatum <- pfromData . fst <$> ptryFromC datum
|
||||
stakeInputDatumF <- pletAllC $ pto stakeInputDatum
|
||||
|
||||
PSpending stakeInputRef <- pmatchC $ pfromData ctxF.purpose
|
||||
|
||||
-- The UTxO we are validating, which is also the input stake.
|
||||
stakeInput <-
|
||||
pletC $
|
||||
pfield @"resolved"
|
||||
#$ passertPJust # "Malformed script context: own input not found"
|
||||
#$ pfindTxInByTxOutRef
|
||||
# (pfield @"_0" # stakeInputRef)
|
||||
# txInfoF.inputs
|
||||
let validatedInput =
|
||||
pfield @"resolved"
|
||||
#$ passertPJust
|
||||
# "Malformed script context: validated input not found"
|
||||
#$ pfindTxInByTxOutRef
|
||||
# (pfield @"_0" # stakeInputRef)
|
||||
# txInfoF.inputs
|
||||
|
||||
stakeInputF <- pletFieldsC @'["address", "value"] stakeInput
|
||||
stakeValidatorAddress = pfield @"address" # validatedInput
|
||||
|
||||
stakeInputContext <-
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
-- Returns stake datum if the given UTxO is a stake UTxO.
|
||||
getStakeDatum :: Term _ (PTxOut :--> PMaybe PStakeDatum) <-
|
||||
pletC $
|
||||
pcon $
|
||||
PStakeInput
|
||||
stakeInputDatum
|
||||
stakeInputF.value
|
||||
plam $ \txOut -> unTermCont $ do
|
||||
txOutF <- pletFieldsC @'["value", "datum", "address"] txOut
|
||||
|
||||
let isStakeUTxO =
|
||||
foldl1
|
||||
(#&&)
|
||||
[ ptraceIfFalse "Carries SST" $
|
||||
sstValueOf # txOutF.value #== 1
|
||||
, ptraceIfFalse "Owned by stake validator" $
|
||||
txOutF.address #== stakeValidatorAddress
|
||||
]
|
||||
|
||||
datum =
|
||||
ptrace "Resolve stake datum" $
|
||||
pfromData $
|
||||
pfromOutputDatum @(PAsData PStakeDatum)
|
||||
# txOutF.datum
|
||||
# txInfoF.datums
|
||||
|
||||
pure $ pif isStakeUTxO (pjust # datum) pnothing
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
-- Find all stake inputs.
|
||||
|
||||
stakeInputDatums <-
|
||||
pletC $
|
||||
pmapMaybe
|
||||
# plam ((getStakeDatum #) . (pfield @"resolved" #))
|
||||
# pfromData txInfoF.inputs
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
-- Assemble the signature context.
|
||||
|
||||
signedBy <- pletC $ pauthorizedBy # authorizationContext txInfoF
|
||||
firstStakeInputDatumF <-
|
||||
pletFieldsC @'["owner", "delegatedTo"] $
|
||||
phead # stakeInputDatums
|
||||
|
||||
let ownerSignsTransaction = signedBy # stakeInputDatumF.owner
|
||||
restOfStakeInputDatums <- pletC $ ptail # stakeInputDatums
|
||||
|
||||
pguardC "All input stakes have the same owner or delegate" $
|
||||
let allHaveSameOwner =
|
||||
pall
|
||||
# plam
|
||||
( (#== firstStakeInputDatumF.owner)
|
||||
. (pfield @"owner" #)
|
||||
)
|
||||
# restOfStakeInputDatums
|
||||
allHaveSameDelegate =
|
||||
pall
|
||||
# plam
|
||||
( (#== firstStakeInputDatumF.delegatedTo)
|
||||
. (pfield @"delegatedTo" #)
|
||||
)
|
||||
# restOfStakeInputDatums
|
||||
in allHaveSameOwner #|| allHaveSameDelegate
|
||||
|
||||
authorizedBy <- pletC $ pauthorizedBy # authorizationContext txInfoF
|
||||
|
||||
let ownerSignsTransaction = authorizedBy # firstStakeInputDatumF.owner
|
||||
|
||||
delegateSignsTransaction =
|
||||
pmaybeData
|
||||
# pconstant False
|
||||
# plam ((signedBy #) . pfromData)
|
||||
# pfromData stakeInputDatumF.delegatedTo
|
||||
# plam ((authorizedBy #) . pfromData)
|
||||
# pfromData firstStakeInputDatumF.delegatedTo
|
||||
|
||||
signedBy =
|
||||
pif
|
||||
ownerSignsTransaction
|
||||
(pcon PSignedByOwner)
|
||||
$ pif
|
||||
delegateSignsTransaction
|
||||
(pcon PSignedByDelegate)
|
||||
$ pcon PUnknownSig
|
||||
|
||||
sigContext <-
|
||||
pletC $
|
||||
pif ownerSignsTransaction (pcon PSignedByOwner) $
|
||||
pif delegateSignsTransaction (pcon PSignedByDelegate) $
|
||||
pcon PUnknownSig
|
||||
pcon $
|
||||
PSigContext
|
||||
firstStakeInputDatumF.owner
|
||||
firstStakeInputDatumF.delegatedTo
|
||||
signedBy
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
stCurrencySymbol <- pletC $ pconstant $ stakeSTSymbol as
|
||||
mintedST <- pletC $ psymbolValueOf # stCurrencySymbol # txInfoF.mint
|
||||
valueSpent <- pletC $ pvalueSpent # txInfoF.inputs
|
||||
spentST <- pletC $ psymbolValueOf # stCurrencySymbol #$ valueSpent
|
||||
-- Find all stake outputs.
|
||||
|
||||
-- The stake validator can only handle one stake in one transaction.
|
||||
let gtAssetClass = passetClass # pconstant gtSym # pconstant gtTn
|
||||
|
||||
pguardC "ST at inputs must be 1" $
|
||||
spentST #== 1
|
||||
|
||||
let oneStakeBurnt =
|
||||
ptraceIfFalse "Exactly one stake st burnt" $
|
||||
mintedST #== (-1)
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
-- Assemble the stake output context.
|
||||
|
||||
let -- Look for the output stake.
|
||||
stakeOutput =
|
||||
pfindJust
|
||||
# plam
|
||||
( \output -> unTermCont $ do
|
||||
outputF <-
|
||||
pletFieldsC @'["address", "value", "datum"]
|
||||
output
|
||||
|
||||
let isStakeOutput =
|
||||
-- The stake should be owned by the stake validator.
|
||||
outputF.address #== stakeInputF.address
|
||||
#&&
|
||||
-- The stake UTxO carries the state thread token.
|
||||
psymbolValueOf
|
||||
# stCurrencySymbol
|
||||
# outputF.value #== 1
|
||||
|
||||
stakeOutputDatum =
|
||||
pfromOutputDatum
|
||||
# outputF.datum
|
||||
# txInfoF.datums
|
||||
|
||||
context =
|
||||
pcon $
|
||||
PStakeOutput
|
||||
(pfromData stakeOutputDatum)
|
||||
outputF.value
|
||||
|
||||
pure $
|
||||
pif
|
||||
isStakeOutput
|
||||
(pjust # context)
|
||||
pnothing
|
||||
)
|
||||
# pfromData txInfoF.outputs
|
||||
|
||||
stakeOutputContext <-
|
||||
-- First step of validating stake outputs. We make sure that every stake
|
||||
-- output UTxO carries correct amount of GTs specified by its datum.
|
||||
--
|
||||
-- Note that non-GT assets are treated transparently.
|
||||
stakeOutputDatums <-
|
||||
pletC $
|
||||
pmatch stakeOutput $ \case
|
||||
-- Stake output found.
|
||||
PJust stakeOutput' -> stakeOutput'
|
||||
-- Stake output not found, meaning the input stake should be burnt.
|
||||
PNothing -> unTermCont $ do
|
||||
pguardC "One stake should be burnt" oneStakeBurnt
|
||||
pmapMaybe
|
||||
# plam
|
||||
( \output ->
|
||||
let validateGT = plam $ \stakeDatum ->
|
||||
let expected = pfield @"stakedAmount" # stakeDatum
|
||||
|
||||
pure $ pcon PStakeBurnt
|
||||
actual =
|
||||
pvalueDiscrete
|
||||
# gtAssetClass
|
||||
# (pfield @"value" # output)
|
||||
in pif
|
||||
(expected #== actual)
|
||||
stakeDatum
|
||||
(ptraceError "Unmatched GT value")
|
||||
in pfmap
|
||||
# validateGT
|
||||
# (getStakeDatum # output)
|
||||
)
|
||||
# pfromData txInfoF.outputs
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
mintedST <- pletC $ sstValueOf # txInfoF.mint
|
||||
|
||||
pguardC "No new SST minted" $
|
||||
foldl1
|
||||
(#||)
|
||||
[ ptraceIfTrue "All stakes burnt" $
|
||||
mintedST #< 0 #&& pnull # stakeOutputDatums
|
||||
, ptraceIfTrue "Nothing burnt" $
|
||||
mintedST #== 0
|
||||
]
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -382,42 +432,79 @@ mkStakeValidator
|
|||
# pconstant propCs
|
||||
# pconstant propTn
|
||||
|
||||
getProposalDatum <- pletC $
|
||||
plam $
|
||||
flip pletAll $ \txOutF ->
|
||||
let isProposalUTxO =
|
||||
passetClassValueOf
|
||||
# txOutF.value
|
||||
# proposalSTClass #== 1
|
||||
proposalDatum =
|
||||
pfromData $
|
||||
pfromOutputDatum @(PAsData PProposalDatum)
|
||||
# txOutF.datum
|
||||
# txInfoF.datums
|
||||
in pif isProposalUTxO (pjust # proposalDatum) pnothing
|
||||
|
||||
let pstMinted =
|
||||
passetClassValueOf # txInfoF.mint # proposalSTClass #== 1
|
||||
|
||||
newProposalContext =
|
||||
pcon $
|
||||
PNewProposal $
|
||||
pfield @"proposalId"
|
||||
#$ passertPJust # "Proposal output should present"
|
||||
#$ pfindJust # getProposalDatum # pfromData txInfoF.outputs
|
||||
|
||||
spendProposalContext =
|
||||
let getProposalRedeemer = plam $ \ref ->
|
||||
flip (ptryFrom @PProposalRedeemer) fst $
|
||||
pto $
|
||||
passertPJust
|
||||
# "Malformed script context: propsoal input not found in redeemer map"
|
||||
#$ plookup
|
||||
# pcon
|
||||
( PSpending $
|
||||
pdcons @_0
|
||||
# pdata ref
|
||||
# pdnil
|
||||
)
|
||||
# txInfoF.redeemers
|
||||
|
||||
getContext = plam $
|
||||
flip pletAll $ \inInfoF ->
|
||||
pfmap
|
||||
# plam
|
||||
( \proposalDatum ->
|
||||
let id = pfield @"proposalId" # proposalDatum
|
||||
status = pfield @"status" # proposalDatum
|
||||
redeemer = getProposalRedeemer # inInfoF.outRef
|
||||
in pcon $ PSpendProposal id status redeemer
|
||||
)
|
||||
#$ getProposalDatum
|
||||
# pfromData inInfoF.resolved
|
||||
|
||||
contexts =
|
||||
pmapMaybe @PList # getContext # pfromData txInfoF.inputs
|
||||
in -- Can only handle one proposal at a time.
|
||||
precList
|
||||
( \_ h t ->
|
||||
pif
|
||||
(pnull # t)
|
||||
(pjust # h)
|
||||
(ptraceError "Ambiguous proposal")
|
||||
)
|
||||
(const pnothing)
|
||||
# contexts
|
||||
|
||||
noProposalContext = pcon PNoProposal
|
||||
|
||||
proposalContext <-
|
||||
pletC $
|
||||
let convertRedeemer = plam $ \(pto -> dt) ->
|
||||
ptryFrom @PProposalRedeemer dt fst
|
||||
|
||||
findRedeemer = plam $ \ref ->
|
||||
plookup
|
||||
# pcon
|
||||
( PSpending $
|
||||
pdcons @_0
|
||||
# pdata ref
|
||||
# pdnil
|
||||
)
|
||||
# txInfoF.redeemers
|
||||
|
||||
f :: Term _ (PTxInInfo :--> PMaybe PTxOutRef)
|
||||
f = plam $ \inInfo ->
|
||||
let value = pfield @"value" #$ pfield @"resolved" # inInfo
|
||||
ref = pfield @"outRef" # inInfo
|
||||
in pif
|
||||
(passetClassValueOf # value # proposalSTClass #== 1)
|
||||
(pjust # ref)
|
||||
pnothing
|
||||
|
||||
proposalRef = pfindJust # f # txInfoF.inputs
|
||||
in pif pstMinted (pcon PNewProposal) $
|
||||
pmaybe
|
||||
# pcon PNoProposal
|
||||
# plam
|
||||
( \((convertRedeemer #) -> proposalRedeemer) ->
|
||||
pcon $ PWithProposalRedeemer proposalRedeemer
|
||||
)
|
||||
#$ proposalRef #>>= findRedeemer
|
||||
pif
|
||||
pstMinted
|
||||
newProposalContext
|
||||
(pfromMaybe # noProposalContext # spendProposalContext)
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -427,12 +514,11 @@ mkStakeValidator
|
|||
plam $ \redeemerContext ->
|
||||
pcon $
|
||||
PStakeRedeemerHandlerContext
|
||||
stakeInputContext
|
||||
stakeOutputContext
|
||||
stakeInputDatums
|
||||
stakeOutputDatums
|
||||
redeemerContext
|
||||
sigContext
|
||||
proposalContext
|
||||
gtAssetClass
|
||||
txInfo
|
||||
|
||||
noMetadataContext <-
|
||||
|
|
@ -445,7 +531,7 @@ mkStakeValidator
|
|||
|
||||
-- Call the redeemer handler.
|
||||
|
||||
stakeRedeemer :: Term _ PStakeRedeemer <- fst <$> ptryFromC redeemer
|
||||
stakeRedeemer <- fst <$> ptryFromC redeemer
|
||||
|
||||
pure $
|
||||
popaque $
|
||||
|
|
@ -472,6 +558,7 @@ mkStakeValidator
|
|||
|
||||
Deposit or withdraw some GT to the stake.
|
||||
|
||||
- Only one stake per tx is supported.
|
||||
- Tx must be signed by the owner.
|
||||
- The 'stakedAmount' field must be updated.
|
||||
- The stake must not be locked.
|
||||
|
|
@ -483,9 +570,9 @@ mkStakeValidator
|
|||
Allow a 'ProposalLock' to be put on the stake in order to vote
|
||||
on a proposal.
|
||||
|
||||
- A proposal token must be spent alongside the stake.
|
||||
- A proposal token must be spent alongside the staked.
|
||||
|
||||
* Its total votes must be correctly updated to include this stake's
|
||||
* Its total votes must be correctly updated to include all stakes'
|
||||
contribution.
|
||||
|
||||
- Tx must be signed by the owner.
|
||||
|
|
@ -494,14 +581,14 @@ mkStakeValidator
|
|||
|
||||
Remove a 'ProposalLock' set when voting on a proposal.
|
||||
|
||||
- A proposal token must be spent alongside the stake.
|
||||
- A proposal token must be spent or minted alongside the stakes.
|
||||
- Tx must be signed by the owner.
|
||||
|
||||
=== 'Destroy'
|
||||
|
||||
Destroy the stake in order to reclaim the min ADA.
|
||||
Destroy stakes in order to reclaim the GTs.
|
||||
|
||||
- The stake must not be locked.
|
||||
- The stakes must not be locked.
|
||||
- Tx must be signed by the owner.
|
||||
|
||||
@since 0.1.0
|
||||
|
|
|
|||
|
|
@ -22,13 +22,17 @@ module Agora.Utils (
|
|||
pstringIntercalate,
|
||||
punwords,
|
||||
pcurrentTimeDuration,
|
||||
pdelete,
|
||||
pdeleteBy,
|
||||
pisSingleton,
|
||||
pfromSingleton,
|
||||
pmapMaybe,
|
||||
) where
|
||||
|
||||
import Plutarch.Api.V1 (PPOSIXTime, PTokenName, PValidatorHash)
|
||||
import Plutarch.Api.V2 (PScriptHash)
|
||||
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (pmatchC)
|
||||
import Plutarch.Extra.Category (PCategory (pidentity))
|
||||
import Plutarch.Extra.Time (PCurrentTime (PCurrentTime))
|
||||
import Plutarch.List (puncons)
|
||||
import Plutarch.Unsafe (punsafeCoerce)
|
||||
import PlutusLedgerApi.V2 (
|
||||
Address (Address),
|
||||
|
|
@ -57,8 +61,8 @@ validatorHashToTokenName (ValidatorHash hash) = TokenName hash
|
|||
|
||||
@since 1.0.0
|
||||
-}
|
||||
pvalidatorHashToTokenName :: forall (s :: S). Term s PValidatorHash -> Term s PTokenName
|
||||
pvalidatorHashToTokenName = punsafeCoerce
|
||||
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.
|
||||
|
|
@ -145,21 +149,23 @@ plistEqualsBy ::
|
|||
(b :: PType)
|
||||
(s :: S).
|
||||
(PIsListLike list1 a, PIsListLike list2 b) =>
|
||||
Term s ((a :--> b :--> PBool) :--> list1 a :--> (list2 b :--> PBool))
|
||||
plistEqualsBy = phoistAcyclic $ pfix # go
|
||||
where
|
||||
go = plam $ \self eq l1 l2 -> unTermCont $ do
|
||||
l1' <- pmatchC $ puncons # l1
|
||||
l2' <- pmatchC $ puncons # l2
|
||||
|
||||
case (l1', l2') of
|
||||
(PJust l1'', PJust l2'') -> do
|
||||
(PPair h1 t1) <- pmatchC l1''
|
||||
(PPair h2 t2) <- pmatchC l2''
|
||||
|
||||
pure $ eq # h1 # h2 #&& self # eq # t1 # t2
|
||||
(PNothing, PNothing) -> pure $ pconstant True
|
||||
_ -> pure $ pconstant False
|
||||
Term s ((a :--> b :--> PBool) :--> list1 a :--> list2 b :--> PBool)
|
||||
plistEqualsBy = phoistAcyclic $
|
||||
plam $ \eq -> pfix #$ plam $ \self l1 l2 ->
|
||||
pelimList
|
||||
( \x xs ->
|
||||
pelimList
|
||||
( \y ys ->
|
||||
-- Avoid comparison if two lists have different length.
|
||||
self # xs # ys #&& eq # x # y
|
||||
)
|
||||
-- l2 is empty, but l1 is not.
|
||||
(pconstant False)
|
||||
l2
|
||||
)
|
||||
-- l1 is empty, so l2 should be empty as well.
|
||||
(pnull # l2)
|
||||
l1
|
||||
|
||||
-- | @since 1.0.0
|
||||
pstringIntercalate ::
|
||||
|
|
@ -190,3 +196,91 @@ 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 :--> 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 :--> list a)
|
||||
pdeleteBy = phoistAcyclic $
|
||||
plam $ \f' x -> plet (f' # x) $ \f ->
|
||||
precList
|
||||
( \self h t ->
|
||||
pif
|
||||
(f # h)
|
||||
t
|
||||
(pcons # h #$ self # t)
|
||||
)
|
||||
(const pnil)
|
||||
|
||||
{- | / 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)
|
||||
|
|
|
|||
925
bench.csv
925
bench.csv
|
|
@ -2,474 +2,461 @@ name,cpu,mem,size
|
|||
Agora/Effects/Treasury Withdrawal Effect/effect/Simple,399131111,1039286,4380
|
||||
Agora/Effects/Treasury Withdrawal Effect/effect/Simple with multiple treasuries ,576074207,1463710,4812
|
||||
Agora/Effects/Treasury Withdrawal Effect/effect/Mixed Assets,570468813,1465515,4750
|
||||
Agora/Effects/Governor Mutation Effect/validator/valid new governor datum/governor validator should pass,119904869,336481,11184
|
||||
Agora/Effects/Governor Mutation Effect/validator/valid new governor datum/effect validator should pass,174447826,463697,4914
|
||||
Agora/Effects/Governor Mutation Effect/validator/valid new governor datum/governor validator should pass,121735742,341472,11153
|
||||
Agora/Effects/Governor Mutation Effect/validator/valid new governor datum/effect validator should pass,177090417,471484,5021
|
||||
Agora/Stake/policy/stakeCreation,57193696,166603,3225
|
||||
Agora/Stake/validator/stakeDepositWithdraw deposit,182637761,498129,6222
|
||||
Agora/Stake/validator/stakeDepositWithdraw withdraw,182637761,498129,6210
|
||||
Agora/Stake/validator/set delegate/override existing delegate,122675859,339769,6249
|
||||
Agora/Stake/validator/set delegate/remove existing delegate,115805652,322809,6179
|
||||
Agora/Stake/validator/set delegate/set delegate to something,120246871,332669,6179
|
||||
Agora/Proposal/policy (proposal creation)/legal/proposal,34052826,101718,2034
|
||||
Agora/Proposal/policy (proposal creation)/legal/governor,332489142,864164,11637
|
||||
Agora/Proposal/policy (proposal creation)/legal/stake,151814104,404130,6889
|
||||
Agora/Proposal/policy (proposal creation)/illegal/invalid next proposal id/proposal,34052826,101718,2034
|
||||
Agora/Proposal/policy (proposal creation)/illegal/invalid next proposal id/stake,151814104,404130,6889
|
||||
Agora/Proposal/policy (proposal creation)/illegal/use other's stake/proposal,34052826,101718,2003
|
||||
Agora/Proposal/policy (proposal creation)/illegal/use other's stake/governor,332489142,864164,11606
|
||||
Agora/Proposal/policy (proposal creation)/illegal/altered stake/proposal,34052826,101718,2034
|
||||
Agora/Proposal/policy (proposal creation)/illegal/invalid stake locks/proposal,34052826,101718,2042
|
||||
Agora/Proposal/policy (proposal creation)/illegal/invalid stake locks/stake,157247764,418780,6897
|
||||
Agora/Proposal/policy (proposal creation)/illegal/has reached maximum proposals limit/proposal,34052826,101718,2054
|
||||
Agora/Proposal/policy (proposal creation)/illegal/has reached maximum proposals limit/stake,164512540,440346,6919
|
||||
Agora/Proposal/policy (proposal creation)/illegal/loose time range/proposal,34052826,101718,2034
|
||||
Agora/Proposal/policy (proposal creation)/illegal/loose time range/stake,151814104,404130,6889
|
||||
Agora/Proposal/policy (proposal creation)/illegal/open time range/proposal,34052826,101718,2030
|
||||
Agora/Proposal/policy (proposal creation)/illegal/open time range/stake,151814104,404130,6885
|
||||
Agora/Proposal/policy (proposal creation)/illegal/invalid proposal status/VotingReady/proposal,34052826,101718,2034
|
||||
Agora/Proposal/policy (proposal creation)/illegal/invalid proposal status/VotingReady/stake,151814104,404130,6889
|
||||
Agora/Proposal/policy (proposal creation)/illegal/invalid proposal status/Locked/proposal,34052826,101718,2034
|
||||
Agora/Proposal/policy (proposal creation)/illegal/invalid proposal status/Locked/stake,151814104,404130,6889
|
||||
Agora/Proposal/policy (proposal creation)/illegal/invalid proposal status/Finished/proposal,34052826,101718,2034
|
||||
Agora/Proposal/policy (proposal creation)/illegal/invalid proposal status/Finished/stake,151814104,404130,6889
|
||||
Agora/Proposal/validator/cosignature/legal/with 1 cosigners: proposal,218125823,619582,11680
|
||||
Agora/Proposal/validator/cosignature/legal/with 5 cosigners: proposal,531693721,1458378,13045
|
||||
Agora/Proposal/validator/cosignature/legal/with 10 cosigners: proposal,1027310682,2746645,14752
|
||||
Agora/Proposal/validator/voting/legal/ordinary/proposal,268264923,732006,12038
|
||||
Agora/Proposal/validator/voting/legal/ordinary/stake,162702421,436978,6724
|
||||
Agora/Proposal/validator/voting/legal/delegate/proposal,273122899,746206,12108
|
||||
Agora/Proposal/validator/voting/legal/delegate/stake,174048586,466701,6829
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Draft to VotingReady/proposal,244983640,688501,12489
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from VotingReady to Locked/proposal,221829223,616387,12252
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Locked to Finished/proposal,235933887,645129,13515
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Locked to Finished/governor,402962600,1095634,12648
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Locked to Finished/authority,15755485,47872,3291
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Draft to VotingReady/proposal,241172350,676273,12210
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from VotingReady to Locked/proposal,218017933,604159,11973
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Locked to Finished/proposal,232122597,632901,13057
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Locked to Finished/governor,400708022,1088128,12283
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Locked to Finished/authority,80911114,217260,2926
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to failed state/from Draft to Finished/proposal,211698609,591948,12245
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to failed state/from VotingReady to Finished/proposal,210024625,582354,12246
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to failed state/from Locked to Finished/proposal,222912570,614760,12246
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to failed state/from Draft to Finished/proposal,207887319,579720,11966
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to failed state/from VotingReady to Finished/proposal,206213335,570126,11967
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to failed state/from Locked to Finished/proposal,219101280,602532,11967
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/advance finished proposals/(negative test)/authority,15755485,47872,3291
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/advance finished proposals/(negative test)/authority,80911114,217260,2926
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/to next state too late/from Locked/governor,402962600,1095634,12648
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/to next state too late/from Locked/authority,15755485,47872,3291
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/to next state too late/from Locked/governor,400708022,1088128,12283
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/to next state too late/from Locked/authority,80911114,217260,2926
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/forget to mint GATs/proposal,232122597,632901,12411
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/mint GATs for wrong validators/proposal,232122597,632901,13057
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/mint GATs for wrong validators/authority,80911114,217260,2926
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/mint GATs with bad token name/proposal,232122597,632901,13089
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/mint GATs with bad token name/authority,12079326,37748,2958
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/wrong GAT datum/proposal,232122597,632901,13051
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/wrong GAT datum/authority,80911114,217260,2920
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/invalid governor output datum/proposal,232122597,632901,13057
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/invalid governor output datum/authority,80911114,217260,2926
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Draft to VotingReady/proposal,319208360,892803,13405
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from VotingReady to Locked/proposal,299748829,830677,13168
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Locked to Finished/proposal,310158607,849431,14431
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Locked to Finished/governor,444697828,1212866,13259
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Locked to Finished/authority,15755485,47872,3902
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Draft to VotingReady/proposal,311585780,868347,12844
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from VotingReady to Locked/proposal,292126249,806221,12607
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Locked to Finished/proposal,302536027,824975,13692
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Locked to Finished/governor,440688637,1199246,12707
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Locked to Finished/authority,80911114,217260,3350
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to failed state/from Draft to Finished/proposal,285923329,796250,13161
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to failed state/from VotingReady to Finished/proposal,284249345,786656,13162
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to failed state/from Locked to Finished/proposal,297137290,819062,13162
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to failed state/from Draft to Finished/proposal,278300749,771794,12600
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to failed state/from VotingReady to Finished/proposal,276626765,762200,12601
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to failed state/from Locked to Finished/proposal,289514710,794606,12601
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/advance finished proposals/(negative test)/authority,15755485,47872,3902
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/advance finished proposals/(negative test)/authority,80911114,217260,3350
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/to next state too late/from Locked/governor,444697828,1212866,13259
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/to next state too late/from Locked/authority,15755485,47872,3902
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/to next state too late/from Locked/governor,440688637,1199246,12707
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/to next state too late/from Locked/authority,80911114,217260,3350
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/forget to mint GATs/proposal,302536027,824975,13046
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/mint GATs for wrong validators/proposal,302536027,824975,13692
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/mint GATs for wrong validators/authority,80911114,217260,3350
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/mint GATs with bad token name/proposal,302536027,824975,13724
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/mint GATs with bad token name/authority,12079326,37748,3382
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/wrong GAT datum/proposal,302536027,824975,13686
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/wrong GAT datum/authority,80911114,217260,3344
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/invalid governor output datum/proposal,302536027,824975,13692
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/invalid governor output datum/authority,80911114,217260,3350
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Draft to VotingReady/proposal,541882520,1505709,16152
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from VotingReady to Locked/proposal,533507647,1473547,15915
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Locked to Finished/proposal,532832767,1462337,17178
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Locked to Finished/governor,569903512,1564562,15090
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Locked to Finished/authority,15755485,47872,5733
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Draft to VotingReady/proposal,522826070,1444569,14751
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from VotingReady to Locked/proposal,514451197,1412407,14514
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Locked to Finished/proposal,513776317,1401197,15599
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Locked to Finished/governor,560630482,1532600,13978
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Locked to Finished/authority,80911114,217260,4621
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to failed state/from Draft to Finished/proposal,508597489,1409156,15908
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to failed state/from VotingReady to Finished/proposal,506923505,1399562,15909
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to failed state/from Locked to Finished/proposal,519811450,1431968,15909
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to failed state/from Draft to Finished/proposal,489541039,1348016,14507
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to failed state/from VotingReady to Finished/proposal,487867055,1338422,14508
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to failed state/from Locked to Finished/proposal,500755000,1370828,14508
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/advance finished proposals/(negative test)/authority,15755485,47872,5733
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/advance finished proposals/(negative test)/authority,80911114,217260,4621
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/to next state too late/from Locked/governor,569903512,1564562,15090
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/to next state too late/from Locked/authority,15755485,47872,5733
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/to next state too late/from Locked/governor,560630482,1532600,13978
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/to next state too late/from Locked/authority,80911114,217260,4621
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/forget to mint GATs/proposal,513776317,1401197,14953
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/mint GATs for wrong validators/proposal,513776317,1401197,15599
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/mint GATs for wrong validators/authority,80911114,217260,4621
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/mint GATs with bad token name/proposal,513776317,1401197,15631
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/mint GATs with bad token name/authority,12079326,37748,4653
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/wrong GAT datum/proposal,513776317,1401197,15593
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/wrong GAT datum/authority,80911114,217260,4614
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/invalid governor output datum/proposal,513776317,1401197,15599
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/invalid governor output datum/authority,80911114,217260,4621
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Draft to VotingReady/proposal,432660726,1221049,13990
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from VotingReady to Locked/proposal,252179943,700115,12662
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Locked to Finished/proposal,266284607,728857,13925
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Locked to Finished/governor,417835896,1137498,12921
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Locked to Finished/authority,15755485,47872,3564
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Draft to VotingReady/proposal,428849436,1208821,13709
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from VotingReady to Locked/proposal,248368653,687887,12382
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Locked to Finished/proposal,262473317,716629,13466
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Locked to Finished/governor,415581318,1129992,12556
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Locked to Finished/authority,80911114,217260,3199
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to failed state/from Draft to Finished/proposal,242049329,675676,12655
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to failed state/from VotingReady to Finished/proposal,240375345,666082,12656
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to failed state/from Locked to Finished/proposal,253263290,698488,12656
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to failed state/from Draft to Finished/proposal,238238039,663448,12375
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to failed state/from VotingReady to Finished/proposal,236564055,653854,12376
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to failed state/from Locked to Finished/proposal,249452000,686260,12376
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/advance finished proposals/(negative test)/authority,15755485,47872,3564
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/advance finished proposals/(negative test)/authority,80911114,217260,3199
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/to next state too late/from Locked/governor,417835896,1137498,12921
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/to next state too late/from Locked/authority,15755485,47872,3564
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/to next state too late/from Locked/governor,415581318,1129992,12556
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/to next state too late/from Locked/authority,80911114,217260,3199
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/forget to mint GATs/proposal,262473317,716629,12820
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/mint GATs for wrong validators/proposal,262473317,716629,13466
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/mint GATs for wrong validators/authority,80911114,217260,3199
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/mint GATs with bad token name/proposal,262473317,716629,13498
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/mint GATs with bad token name/authority,12079326,37748,3231
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/wrong GAT datum/proposal,262473317,716629,13460
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/wrong GAT datum/authority,80911114,217260,3193
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/invalid governor output datum/proposal,262473317,716629,13466
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/invalid governor output datum/authority,80911114,217260,3199
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Draft to VotingReady/proposal,506885446,1425351,14905
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from VotingReady to Locked/proposal,330099549,914405,13578
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Locked to Finished/proposal,340509327,933159,14841
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Locked to Finished/governor,459571124,1254730,13532
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Locked to Finished/authority,15755485,47872,4175
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Draft to VotingReady/proposal,499262866,1400895,14345
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from VotingReady to Locked/proposal,322476969,889949,13017
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Locked to Finished/proposal,332886747,908703,14102
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Locked to Finished/governor,455561933,1241110,12980
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Locked to Finished/authority,80911114,217260,3623
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to failed state/from Draft to Finished/proposal,316274049,879978,13571
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to failed state/from VotingReady to Finished/proposal,314600065,870384,13572
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to failed state/from Locked to Finished/proposal,327488010,902790,13572
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to failed state/from Draft to Finished/proposal,308651469,855522,13010
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to failed state/from VotingReady to Finished/proposal,306977485,845928,13011
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to failed state/from Locked to Finished/proposal,319865430,878334,13011
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/advance finished proposals/(negative test)/authority,15755485,47872,4175
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/advance finished proposals/(negative test)/authority,80911114,217260,3623
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/to next state too late/from Locked/governor,459571124,1254730,13532
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/to next state too late/from Locked/authority,15755485,47872,4175
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/to next state too late/from Locked/governor,455561933,1241110,12980
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/to next state too late/from Locked/authority,80911114,217260,3623
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/forget to mint GATs/proposal,332886747,908703,13456
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/mint GATs for wrong validators/proposal,332886747,908703,14102
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/mint GATs for wrong validators/authority,80911114,217260,3623
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/mint GATs with bad token name/proposal,332886747,908703,14134
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/mint GATs with bad token name/authority,12079326,37748,3655
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/wrong GAT datum/proposal,332886747,908703,14096
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/wrong GAT datum/authority,80911114,217260,3617
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/invalid governor output datum/proposal,332886747,908703,14102
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/invalid governor output datum/authority,80911114,217260,3623
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Draft to VotingReady/proposal,729559606,2038257,17651
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from VotingReady to Locked/proposal,563858367,1557275,16324
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Locked to Finished/proposal,563183487,1546065,17587
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Locked to Finished/governor,584776808,1606426,15363
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Locked to Finished/authority,15755485,47872,6006
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Draft to VotingReady/proposal,710503156,1977117,16251
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from VotingReady to Locked/proposal,544801917,1496135,14923
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Locked to Finished/proposal,544127037,1484925,16008
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Locked to Finished/governor,575503778,1574464,14251
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Locked to Finished/authority,80911114,217260,4894
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to failed state/from Draft to Finished/proposal,538948209,1492884,16317
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to failed state/from VotingReady to Finished/proposal,537274225,1483290,16318
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to failed state/from Locked to Finished/proposal,550162170,1515696,16318
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to failed state/from Draft to Finished/proposal,519891759,1431744,14916
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to failed state/from VotingReady to Finished/proposal,518217775,1422150,14917
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to failed state/from Locked to Finished/proposal,531105720,1454556,14917
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/advance finished proposals/(negative test)/authority,15755485,47872,6006
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/advance finished proposals/(negative test)/authority,80911114,217260,4894
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/to next state too late/from Locked/governor,584776808,1606426,15363
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/to next state too late/from Locked/authority,15755485,47872,6006
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/to next state too late/from Locked/governor,575503778,1574464,14251
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/to next state too late/from Locked/authority,80911114,217260,4894
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/forget to mint GATs/proposal,544127037,1484925,15362
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/mint GATs for wrong validators/proposal,544127037,1484925,16008
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/mint GATs for wrong validators/authority,80911114,217260,4894
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/mint GATs with bad token name/proposal,544127037,1484925,16040
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/mint GATs with bad token name/authority,12079326,37748,4926
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/wrong GAT datum/proposal,544127037,1484925,16002
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/wrong GAT datum/authority,80911114,217260,4888
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/invalid governor output datum/proposal,544127037,1484925,16008
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/invalid governor output datum/authority,80911114,217260,4894
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Draft to VotingReady/proposal,682420527,1932425,15866
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from VotingReady to Locked/proposal,290118343,804775,13174
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Locked to Finished/proposal,304223007,833517,14437
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Locked to Finished/governor,436427516,1189828,13263
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Locked to Finished/authority,15755485,47872,3906
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Draft to VotingReady/proposal,678609237,1920197,15587
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from VotingReady to Locked/proposal,286307053,792547,12894
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Locked to Finished/proposal,300411717,821289,13978
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Locked to Finished/governor,434172938,1182322,12897
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Locked to Finished/authority,80911114,217260,3540
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to failed state/from Draft to Finished/proposal,279987729,780336,13167
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to failed state/from VotingReady to Finished/proposal,278313745,770742,13168
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to failed state/from Locked to Finished/proposal,291201690,803148,13168
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to failed state/from Draft to Finished/proposal,276176439,768108,12887
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to failed state/from VotingReady to Finished/proposal,274502455,758514,12888
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to failed state/from Locked to Finished/proposal,287390400,790920,12888
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/advance finished proposals/(negative test)/authority,15755485,47872,3906
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/advance finished proposals/(negative test)/authority,80911114,217260,3540
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/to next state too late/from Locked/governor,436427516,1189828,13263
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/to next state too late/from Locked/authority,15755485,47872,3906
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/to next state too late/from Locked/governor,434172938,1182322,12897
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/to next state too late/from Locked/authority,80911114,217260,3540
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/forget to mint GATs/proposal,300411717,821289,13333
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/mint GATs for wrong validators/proposal,300411717,821289,13978
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/mint GATs for wrong validators/authority,80911114,217260,3540
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/mint GATs with bad token name/proposal,300411717,821289,14010
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/mint GATs with bad token name/authority,12079326,37748,3572
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/wrong GAT datum/proposal,300411717,821289,13972
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/wrong GAT datum/authority,80911114,217260,3534
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/invalid governor output datum/proposal,300411717,821289,13978
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/invalid governor output datum/authority,80911114,217260,3540
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Draft to VotingReady/proposal,756645247,2136727,16782
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from VotingReady to Locked/proposal,368037949,1019065,14089
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Locked to Finished/proposal,378447727,1037819,15352
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Locked to Finished/governor,478162744,1307060,13873
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Locked to Finished/authority,15755485,47872,4516
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Draft to VotingReady/proposal,749022667,2112271,16222
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from VotingReady to Locked/proposal,360415369,994609,13530
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Locked to Finished/proposal,370825147,1013363,14614
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Locked to Finished/governor,474153553,1293440,13321
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Locked to Finished/authority,80911114,217260,3964
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to failed state/from Draft to Finished/proposal,354212449,984638,14082
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to failed state/from VotingReady to Finished/proposal,352538465,975044,14083
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to failed state/from Locked to Finished/proposal,365426410,1007450,14083
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to failed state/from Draft to Finished/proposal,346589869,960182,13523
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to failed state/from VotingReady to Finished/proposal,344915885,950588,13524
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to failed state/from Locked to Finished/proposal,357803830,982994,13524
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/advance finished proposals/(negative test)/authority,15755485,47872,4516
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/advance finished proposals/(negative test)/authority,80911114,217260,3964
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/to next state too late/from Locked/governor,478162744,1307060,13873
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/to next state too late/from Locked/authority,15755485,47872,4516
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/to next state too late/from Locked/governor,474153553,1293440,13321
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/to next state too late/from Locked/authority,80911114,217260,3964
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/forget to mint GATs/proposal,370825147,1013363,13968
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/mint GATs for wrong validators/proposal,370825147,1013363,14614
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/mint GATs for wrong validators/authority,80911114,217260,3964
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/mint GATs with bad token name/proposal,370825147,1013363,14646
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/mint GATs with bad token name/authority,12079326,37748,3996
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/wrong GAT datum/proposal,370825147,1013363,14608
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/wrong GAT datum/authority,80911114,217260,3958
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/invalid governor output datum/proposal,370825147,1013363,14614
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/invalid governor output datum/authority,80911114,217260,3964
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Draft to VotingReady/proposal,979319407,2749633,19529
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from VotingReady to Locked/proposal,601796767,1661935,16836
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Locked to Finished/proposal,601121887,1650725,18099
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Locked to Finished/governor,603368428,1658756,15704
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Locked to Finished/authority,15755485,47872,6347
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Draft to VotingReady/proposal,960262957,2688493,18128
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from VotingReady to Locked/proposal,582740317,1600795,15436
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Locked to Finished/proposal,582065437,1589585,16520
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Locked to Finished/governor,594095398,1626794,14592
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Locked to Finished/authority,80911114,217260,5235
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to failed state/from Draft to Finished/proposal,576886609,1597544,16829
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to failed state/from VotingReady to Finished/proposal,575212625,1587950,16830
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to failed state/from Locked to Finished/proposal,588100570,1620356,16830
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to failed state/from Draft to Finished/proposal,557830159,1536404,15429
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to failed state/from VotingReady to Finished/proposal,556156175,1526810,15430
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to failed state/from Locked to Finished/proposal,569044120,1559216,15430
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/advance finished proposals/(negative test)/authority,15755485,47872,6347
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/advance finished proposals/(negative test)/authority,80911114,217260,5235
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/to next state too late/from Locked/governor,603368428,1658756,15704
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/to next state too late/from Locked/authority,15755485,47872,6347
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/to next state too late/from Locked/governor,594095398,1626794,14592
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/to next state too late/from Locked/authority,80911114,217260,5235
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/forget to mint GATs/proposal,582065437,1589585,15874
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/mint GATs for wrong validators/proposal,582065437,1589585,16520
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/mint GATs for wrong validators/authority,80911114,217260,5235
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/mint GATs with bad token name/proposal,582065437,1589585,16552
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/mint GATs with bad token name/authority,12079326,37748,5267
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/wrong GAT datum/proposal,582065437,1589585,16514
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/wrong GAT datum/authority,80911114,217260,5229
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/invalid governor output datum/proposal,582065437,1589585,16520
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/invalid governor output datum/authority,80911114,217260,5235
|
||||
Agora/Proposal/validator/unlocking/legal/with 1 proposals/voter: retract votes while voting/stake,147337981,392782,6702
|
||||
Agora/Proposal/validator/unlocking/legal/with 1 proposals/voter: retract votes while voting/proposal,248777421,680471,12017
|
||||
Agora/Proposal/validator/unlocking/legal/with 1 proposals/voter/creator: retract votes while voting/stake,153687199,410890,6718
|
||||
Agora/Proposal/validator/unlocking/legal/with 1 proposals/voter/creator: retract votes while voting/proposal,266163719,729912,12028
|
||||
Agora/Proposal/validator/unlocking/legal/with 1 proposals/creator: remove creator locks when finished/stake,146299704,389984,6700
|
||||
Agora/Proposal/validator/unlocking/legal/with 1 proposals/creator: remove creator locks when finished/proposal,237150672,650439,12014
|
||||
Agora/Proposal/validator/unlocking/legal/with 1 proposals/voter/creator: remove all locks when finished/stake,150455953,401836,6716
|
||||
Agora/Proposal/validator/unlocking/legal/with 1 proposals/voter/creator: remove all locks when finished/proposal,245388141,674947,12026
|
||||
Agora/Proposal/validator/unlocking/legal/with 1 proposals/voter: unlock after voting/Locked/stake,147337981,392782,6706
|
||||
Agora/Proposal/validator/unlocking/legal/with 1 proposals/voter: unlock after voting/Locked/proposal,233077780,642214,12021
|
||||
Agora/Proposal/validator/unlocking/legal/with 1 proposals/voter: unlock after voting/Finished/stake,147337981,392782,6706
|
||||
Agora/Proposal/validator/unlocking/legal/with 1 proposals/voter: unlock after voting/Finished/proposal,233643269,643416,12021
|
||||
Agora/Proposal/validator/unlocking/legal/with 1 proposals/voter/creator: remove vote locks when locked/stake,153687199,410890,6722
|
||||
Agora/Proposal/validator/unlocking/legal/with 1 proposals/voter/creator: remove vote locks when locked/proposal,251029567,692857,12032
|
||||
Agora/Proposal/validator/unlocking/legal/with 5 proposals/voter: retract votes while voting/stake,294042173,755738,9003
|
||||
Agora/Proposal/validator/unlocking/legal/with 5 proposals/voter: retract votes while voting/proposal,384044641,1002847,14294
|
||||
Agora/Proposal/validator/unlocking/legal/with 5 proposals/voter/creator: retract votes while voting/stake,325788263,846278,9079
|
||||
Agora/Proposal/validator/unlocking/legal/with 5 proposals/voter/creator: retract votes while voting/proposal,453034171,1203600,14345
|
||||
Agora/Proposal/validator/unlocking/legal/with 5 proposals/creator: remove creator locks when finished/stake,288850788,741748,8993
|
||||
Agora/Proposal/validator/unlocking/legal/with 5 proposals/creator: remove creator locks when finished/proposal,358441456,945903,14287
|
||||
Agora/Proposal/validator/unlocking/legal/with 5 proposals/voter/creator: remove all locks when finished/stake,309632033,801008,9073
|
||||
Agora/Proposal/validator/unlocking/legal/with 5 proposals/voter/creator: remove all locks when finished/proposal,396633649,1057259,14339
|
||||
Agora/Proposal/validator/unlocking/legal/with 5 proposals/voter: unlock after voting/Locked/stake,294042173,755738,9023
|
||||
Agora/Proposal/validator/unlocking/legal/with 5 proposals/voter: unlock after voting/Locked/proposal,358521672,948870,14314
|
||||
Agora/Proposal/validator/unlocking/legal/with 5 proposals/voter: unlock after voting/Finished/stake,294042173,755738,9023
|
||||
Agora/Proposal/validator/unlocking/legal/with 5 proposals/voter: unlock after voting/Finished/proposal,359087161,950072,14314
|
||||
Agora/Proposal/validator/unlocking/legal/with 5 proposals/voter/creator: remove vote locks when locked/stake,325788263,846278,9099
|
||||
Agora/Proposal/validator/unlocking/legal/with 5 proposals/voter/creator: remove vote locks when locked/proposal,428076691,1150825,14365
|
||||
Agora/Proposal/validator/unlocking/legal/with 10 proposals/voter: retract votes while voting/stake,477422413,1209433,11879
|
||||
Agora/Proposal/validator/unlocking/legal/with 10 proposals/voter: retract votes while voting/proposal,553128666,1405817,17140
|
||||
Agora/Proposal/validator/unlocking/legal/with 10 proposals/voter/creator: retract votes while voting/stake,540914593,1390513,12030
|
||||
Agora/Proposal/validator/unlocking/legal/with 10 proposals/voter/creator: retract votes while voting/proposal,686622236,1795710,17241
|
||||
Agora/Proposal/validator/unlocking/legal/with 10 proposals/creator: remove creator locks when finished/stake,467039643,1181453,11859
|
||||
Agora/Proposal/validator/unlocking/legal/with 10 proposals/creator: remove creator locks when finished/proposal,510054936,1315233,17128
|
||||
Agora/Proposal/validator/unlocking/legal/with 10 proposals/voter/creator: remove all locks when finished/stake,508602133,1299973,12019
|
||||
Agora/Proposal/validator/unlocking/legal/with 10 proposals/voter/creator: remove all locks when finished/proposal,585690534,1535149,17230
|
||||
Agora/Proposal/validator/unlocking/legal/with 10 proposals/voter: unlock after voting/Locked/stake,477422413,1209433,11919
|
||||
Agora/Proposal/validator/unlocking/legal/with 10 proposals/voter: unlock after voting/Locked/proposal,515326537,1332190,17180
|
||||
Agora/Proposal/validator/unlocking/legal/with 10 proposals/voter: unlock after voting/Finished/stake,477422413,1209433,11919
|
||||
Agora/Proposal/validator/unlocking/legal/with 10 proposals/voter: unlock after voting/Finished/proposal,515892026,1333392,17180
|
||||
Agora/Proposal/validator/unlocking/legal/with 10 proposals/voter/creator: remove vote locks when locked/stake,540914593,1390513,12070
|
||||
Agora/Proposal/validator/unlocking/legal/with 10 proposals/voter/creator: remove vote locks when locked/proposal,649385596,1723285,17281
|
||||
Agora/Proposal/validator/unlocking/legal/with 42 proposals/voter: retract votes while voting/stake,1651055949,4113081,30401
|
||||
Agora/Proposal/validator/unlocking/legal/with 42 proposals/voter: retract votes while voting/proposal,1635266426,3984825,35451
|
||||
Agora/Proposal/validator/unlocking/legal/with 42 proposals/voter/creator: retract votes while voting/stake,1917723105,4873617,31089
|
||||
Agora/Proposal/validator/unlocking/legal/with 42 proposals/voter/creator: retract votes while voting/proposal,2181585852,5585214,35910
|
||||
Agora/Proposal/validator/unlocking/legal/with 42 proposals/creator: remove creator locks when finished/stake,1607448315,3995565,30317
|
||||
Agora/Proposal/validator/unlocking/legal/with 42 proposals/creator: remove creator locks when finished/proposal,1480381208,3678945,35407
|
||||
Agora/Proposal/validator/unlocking/legal/with 42 proposals/voter/creator: remove all locks when finished/stake,1782010773,4493349,31028
|
||||
Agora/Proposal/validator/unlocking/legal/with 42 proposals/voter/creator: remove all locks when finished/proposal,1795654598,4593645,35849
|
||||
Agora/Proposal/validator/unlocking/legal/with 42 proposals/voter: unlock after voting/Locked/stake,1651055949,4113081,30570
|
||||
Agora/Proposal/validator/unlocking/legal/with 42 proposals/voter: unlock after voting/Locked/proposal,1518877673,3785438,35620
|
||||
Agora/Proposal/validator/unlocking/legal/with 42 proposals/voter: unlock after voting/Finished/stake,1651055949,4113081,30570
|
||||
Agora/Proposal/validator/unlocking/legal/with 42 proposals/voter: unlock after voting/Finished/proposal,1519443162,3786640,35620
|
||||
Agora/Proposal/validator/unlocking/legal/with 42 proposals/voter/creator: remove vote locks when locked/stake,1917723105,4873617,31258
|
||||
Agora/Proposal/validator/unlocking/legal/with 42 proposals/voter/creator: remove vote locks when locked/proposal,2065762588,5387029,36079
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 1 proposals/retract votes while not voting/role: Voter , status: Draft/stake",147337981,392782,6702
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 1 proposals/retract votes while not voting/role: Voter , status: Locked/stake",147337981,392782,6702
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 1 proposals/retract votes while not voting/role: Voter , status: Finished/stake",147337981,392782,6702
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 1 proposals/retract votes while not voting/role: Creator , status: Draft/stake",144619286,391178,6704
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 1 proposals/retract votes while not voting/role: Creator , status: Locked/stake",144619286,391178,6704
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 1 proposals/retract votes while not voting/role: Creator , status: Finished/stake",144619286,391178,6704
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 1 proposals/retract votes while not voting/role: Both , status: Draft/stake",153687199,410890,6718
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 1 proposals/retract votes while not voting/role: Both , status: Locked/stake",153687199,410890,6718
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 1 proposals/retract votes while not voting/role: Both , status: Finished/stake",153687199,410890,6718
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 1 proposals/retract votes while not voting/role: Irrelevant , status: Draft/stake",138270068,373070,6684
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 1 proposals/retract votes while not voting/role: Irrelevant , status: Locked/stake",138270068,373070,6684
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 1 proposals/retract votes while not voting/role: Irrelevant , status: Finished/stake",138270068,373070,6684
|
||||
Agora/Proposal/validator/unlocking/illegal/with 1 proposals/unlock an irrelevant stake/status: Draft retract votes: True/stake,138270068,373070,6684
|
||||
Agora/Proposal/validator/unlocking/illegal/with 1 proposals/unlock an irrelevant stake/status: Draft retract votes: False/stake,138270068,373070,6684
|
||||
Agora/Proposal/validator/unlocking/illegal/with 1 proposals/unlock an irrelevant stake/status: VotingReady retract votes: True/stake,138270068,373070,6684
|
||||
Agora/Proposal/validator/unlocking/illegal/with 1 proposals/unlock an irrelevant stake/status: VotingReady retract votes: False/stake,138270068,373070,6684
|
||||
Agora/Proposal/validator/unlocking/illegal/with 1 proposals/unlock an irrelevant stake/status: Locked retract votes: True/stake,138270068,373070,6684
|
||||
Agora/Proposal/validator/unlocking/illegal/with 1 proposals/unlock an irrelevant stake/status: Locked retract votes: False/stake,138270068,373070,6684
|
||||
Agora/Proposal/validator/unlocking/illegal/with 1 proposals/unlock an irrelevant stake/status: Finished retract votes: True/stake,138270068,373070,6684
|
||||
Agora/Proposal/validator/unlocking/illegal/with 1 proposals/unlock an irrelevant stake/status: Finished retract votes: False/stake,138270068,373070,6684
|
||||
Agora/Proposal/validator/unlocking/illegal/with 1 proposals/remove creator too early/status: Draft/stake,146299704,389984,6700
|
||||
Agora/Proposal/validator/unlocking/illegal/with 1 proposals/remove creator too early/status: VotingReady/stake,146299704,389984,6700
|
||||
Agora/Proposal/validator/unlocking/illegal/with 1 proposals/remove creator too early/status: Locked/stake,146299704,389984,6700
|
||||
Agora/Proposal/validator/unlocking/illegal/with 1 proposals/creator: retract votes/stake,146299704,389984,6698
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 5 proposals/retract votes while not voting/role: Voter , status: Draft/stake",294042173,755738,9003
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 5 proposals/retract votes while not voting/role: Voter , status: Locked/stake",294042173,755738,9003
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 5 proposals/retract votes while not voting/role: Voter , status: Finished/stake",294042173,755738,9003
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 5 proposals/retract votes while not voting/role: Creator , status: Draft/stake",290272026,763438,9009
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 5 proposals/retract votes while not voting/role: Creator , status: Locked/stake",290272026,763438,9009
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 5 proposals/retract votes while not voting/role: Creator , status: Finished/stake",290272026,763438,9009
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 5 proposals/retract votes while not voting/role: Both , status: Draft/stake",325788263,846278,9079
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 5 proposals/retract votes while not voting/role: Both , status: Locked/stake",325788263,846278,9079
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 5 proposals/retract votes while not voting/role: Both , status: Finished/stake",325788263,846278,9079
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 5 proposals/retract votes while not voting/role: Irrelevant , status: Draft/stake",258525936,672898,8920
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 5 proposals/retract votes while not voting/role: Irrelevant , status: Locked/stake",258525936,672898,8920
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 5 proposals/retract votes while not voting/role: Irrelevant , status: Finished/stake",258525936,672898,8920
|
||||
Agora/Proposal/validator/unlocking/illegal/with 5 proposals/unlock an irrelevant stake/status: Draft retract votes: True/stake,258525936,672898,8920
|
||||
Agora/Proposal/validator/unlocking/illegal/with 5 proposals/unlock an irrelevant stake/status: Draft retract votes: False/stake,258525936,672898,8920
|
||||
Agora/Proposal/validator/unlocking/illegal/with 5 proposals/unlock an irrelevant stake/status: VotingReady retract votes: True/stake,258525936,672898,8920
|
||||
Agora/Proposal/validator/unlocking/illegal/with 5 proposals/unlock an irrelevant stake/status: VotingReady retract votes: False/stake,258525936,672898,8920
|
||||
Agora/Proposal/validator/unlocking/illegal/with 5 proposals/unlock an irrelevant stake/status: Locked retract votes: True/stake,258525936,672898,8920
|
||||
Agora/Proposal/validator/unlocking/illegal/with 5 proposals/unlock an irrelevant stake/status: Locked retract votes: False/stake,258525936,672898,8920
|
||||
Agora/Proposal/validator/unlocking/illegal/with 5 proposals/unlock an irrelevant stake/status: Finished retract votes: True/stake,258525936,672898,8920
|
||||
Agora/Proposal/validator/unlocking/illegal/with 5 proposals/unlock an irrelevant stake/status: Finished retract votes: False/stake,258525936,672898,8920
|
||||
Agora/Proposal/validator/unlocking/illegal/with 5 proposals/remove creator too early/status: Draft/stake,288850788,741748,8993
|
||||
Agora/Proposal/validator/unlocking/illegal/with 5 proposals/remove creator too early/status: VotingReady/stake,288850788,741748,8993
|
||||
Agora/Proposal/validator/unlocking/illegal/with 5 proposals/remove creator too early/status: Locked/stake,288850788,741748,8993
|
||||
Agora/Proposal/validator/unlocking/illegal/with 5 proposals/creator: retract votes/stake,288850788,741748,8982
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 10 proposals/retract votes while not voting/role: Voter , status: Draft/stake",477422413,1209433,11879
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 10 proposals/retract votes while not voting/role: Voter , status: Locked/stake",477422413,1209433,11879
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 10 proposals/retract votes while not voting/role: Voter , status: Finished/stake",477422413,1209433,11879
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 10 proposals/retract votes while not voting/role: Creator , status: Draft/stake",472337951,1228763,11890
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 10 proposals/retract votes while not voting/role: Creator , status: Locked/stake",472337951,1228763,11890
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 10 proposals/retract votes while not voting/role: Creator , status: Finished/stake",472337951,1228763,11890
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 10 proposals/retract votes while not voting/role: Both , status: Draft/stake",540914593,1390513,12030
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 10 proposals/retract votes while not voting/role: Both , status: Locked/stake",540914593,1390513,12030
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 10 proposals/retract votes while not voting/role: Both , status: Finished/stake",540914593,1390513,12030
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 10 proposals/retract votes while not voting/role: Irrelevant , status: Draft/stake",408845771,1047683,11716
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 10 proposals/retract votes while not voting/role: Irrelevant , status: Locked/stake",408845771,1047683,11716
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 10 proposals/retract votes while not voting/role: Irrelevant , status: Finished/stake",408845771,1047683,11716
|
||||
Agora/Proposal/validator/unlocking/illegal/with 10 proposals/unlock an irrelevant stake/status: Draft retract votes: True/stake,408845771,1047683,11716
|
||||
Agora/Proposal/validator/unlocking/illegal/with 10 proposals/unlock an irrelevant stake/status: Draft retract votes: False/stake,408845771,1047683,11716
|
||||
Agora/Proposal/validator/unlocking/illegal/with 10 proposals/unlock an irrelevant stake/status: VotingReady retract votes: True/stake,408845771,1047683,11716
|
||||
Agora/Proposal/validator/unlocking/illegal/with 10 proposals/unlock an irrelevant stake/status: VotingReady retract votes: False/stake,408845771,1047683,11716
|
||||
Agora/Proposal/validator/unlocking/illegal/with 10 proposals/unlock an irrelevant stake/status: Locked retract votes: True/stake,408845771,1047683,11716
|
||||
Agora/Proposal/validator/unlocking/illegal/with 10 proposals/unlock an irrelevant stake/status: Locked retract votes: False/stake,408845771,1047683,11716
|
||||
Agora/Proposal/validator/unlocking/illegal/with 10 proposals/unlock an irrelevant stake/status: Finished retract votes: True/stake,408845771,1047683,11716
|
||||
Agora/Proposal/validator/unlocking/illegal/with 10 proposals/unlock an irrelevant stake/status: Finished retract votes: False/stake,408845771,1047683,11716
|
||||
Agora/Proposal/validator/unlocking/illegal/with 10 proposals/remove creator too early/status: Draft/stake,467039643,1181453,11859
|
||||
Agora/Proposal/validator/unlocking/illegal/with 10 proposals/remove creator too early/status: VotingReady/stake,467039643,1181453,11859
|
||||
Agora/Proposal/validator/unlocking/illegal/with 10 proposals/remove creator too early/status: Locked/stake,467039643,1181453,11859
|
||||
Agora/Proposal/validator/unlocking/illegal/with 10 proposals/creator: retract votes/stake,467039643,1181453,11839
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 42 proposals/retract votes while not voting/role: Voter , status: Draft/stake",1651055949,4113081,30401
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 42 proposals/retract votes while not voting/role: Voter , status: Locked/stake",1651055949,4113081,30401
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 42 proposals/retract votes while not voting/role: Voter , status: Finished/stake",1651055949,4113081,30401
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 42 proposals/retract votes while not voting/role: Creator , status: Draft/stake",1637559871,4206843,30463
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 42 proposals/retract votes while not voting/role: Creator , status: Locked/stake",1637559871,4206843,30463
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 42 proposals/retract votes while not voting/role: Creator , status: Finished/stake",1637559871,4206843,30463
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 42 proposals/retract votes while not voting/role: Both , status: Draft/stake",1917723105,4873617,31089
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 42 proposals/retract votes while not voting/role: Both , status: Locked/stake",1917723105,4873617,31089
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 42 proposals/retract votes while not voting/role: Both , status: Finished/stake",1917723105,4873617,31089
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 42 proposals/retract votes while not voting/role: Irrelevant , status: Draft/stake",1370892715,3446307,29688
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 42 proposals/retract votes while not voting/role: Irrelevant , status: Locked/stake",1370892715,3446307,29688
|
||||
"Agora/Proposal/validator/unlocking/illegal/with 42 proposals/retract votes while not voting/role: Irrelevant , status: Finished/stake",1370892715,3446307,29688
|
||||
Agora/Proposal/validator/unlocking/illegal/with 42 proposals/unlock an irrelevant stake/status: Draft retract votes: True/stake,1370892715,3446307,29688
|
||||
Agora/Proposal/validator/unlocking/illegal/with 42 proposals/unlock an irrelevant stake/status: Draft retract votes: False/stake,1370892715,3446307,29688
|
||||
Agora/Proposal/validator/unlocking/illegal/with 42 proposals/unlock an irrelevant stake/status: VotingReady retract votes: True/stake,1370892715,3446307,29688
|
||||
Agora/Proposal/validator/unlocking/illegal/with 42 proposals/unlock an irrelevant stake/status: VotingReady retract votes: False/stake,1370892715,3446307,29688
|
||||
Agora/Proposal/validator/unlocking/illegal/with 42 proposals/unlock an irrelevant stake/status: Locked retract votes: True/stake,1370892715,3446307,29688
|
||||
Agora/Proposal/validator/unlocking/illegal/with 42 proposals/unlock an irrelevant stake/status: Locked retract votes: False/stake,1370892715,3446307,29688
|
||||
Agora/Proposal/validator/unlocking/illegal/with 42 proposals/unlock an irrelevant stake/status: Finished retract votes: True/stake,1370892715,3446307,29688
|
||||
Agora/Proposal/validator/unlocking/illegal/with 42 proposals/unlock an irrelevant stake/status: Finished retract votes: False/stake,1370892715,3446307,29688
|
||||
Agora/Proposal/validator/unlocking/illegal/with 42 proposals/remove creator too early/status: Draft/stake,1607448315,3995565,30317
|
||||
Agora/Proposal/validator/unlocking/illegal/with 42 proposals/remove creator too early/status: VotingReady/stake,1607448315,3995565,30317
|
||||
Agora/Proposal/validator/unlocking/illegal/with 42 proposals/remove creator too early/status: Locked/stake,1607448315,3995565,30317
|
||||
Agora/Proposal/validator/unlocking/illegal/with 42 proposals/creator: retract votes/stake,1607448315,3995565,30233
|
||||
Agora/Stake/validator/stakeDepositWithdraw deposit,131776572,375179,7328
|
||||
Agora/Stake/validator/stakeDepositWithdraw withdraw,131776572,375179,7320
|
||||
Agora/Stake/validator/set delegate/override existing delegate,155110062,435004,7459
|
||||
Agora/Stake/validator/set delegate/remove existing delegate,145775066,411616,7389
|
||||
Agora/Stake/validator/set delegate/set delegate to something,152681074,427904,7389
|
||||
Agora/Proposal/policy (proposal creation)/legal/proposal,34052826,101718,2040
|
||||
Agora/Proposal/policy (proposal creation)/legal/governor,275969940,726895,11606
|
||||
Agora/Proposal/policy (proposal creation)/legal/stake,285591523,773491,8105
|
||||
Agora/Proposal/policy (proposal creation)/illegal/invalid next proposal id/proposal,34052826,101718,2040
|
||||
Agora/Proposal/policy (proposal creation)/illegal/invalid next proposal id/stake,285591523,773491,8105
|
||||
Agora/Proposal/policy (proposal creation)/illegal/use other's stake/proposal,34052826,101718,2009
|
||||
Agora/Proposal/policy (proposal creation)/illegal/use other's stake/governor,275969940,726895,11575
|
||||
Agora/Proposal/policy (proposal creation)/illegal/altered stake/proposal,34052826,101718,2040
|
||||
Agora/Proposal/policy (proposal creation)/illegal/invalid stake locks/proposal,34052826,101718,2048
|
||||
Agora/Proposal/policy (proposal creation)/illegal/invalid stake locks/governor,275969940,726895,11614
|
||||
Agora/Proposal/policy (proposal creation)/illegal/has reached maximum proposals limit/proposal,34052826,101718,2060
|
||||
Agora/Proposal/policy (proposal creation)/illegal/has reached maximum proposals limit/stake,298289959,809707,8136
|
||||
Agora/Proposal/policy (proposal creation)/illegal/loose time range/proposal,34052826,101718,2040
|
||||
Agora/Proposal/policy (proposal creation)/illegal/loose time range/stake,285591523,773491,8105
|
||||
Agora/Proposal/policy (proposal creation)/illegal/open time range/proposal,34052826,101718,2036
|
||||
Agora/Proposal/policy (proposal creation)/illegal/open time range/stake,285591523,773491,8101
|
||||
Agora/Proposal/policy (proposal creation)/illegal/invalid proposal status/VotingReady/proposal,34052826,101718,2040
|
||||
Agora/Proposal/policy (proposal creation)/illegal/invalid proposal status/VotingReady/stake,285591523,773491,8105
|
||||
Agora/Proposal/policy (proposal creation)/illegal/invalid proposal status/Locked/proposal,34052826,101718,2040
|
||||
Agora/Proposal/policy (proposal creation)/illegal/invalid proposal status/Locked/stake,285591523,773491,8105
|
||||
Agora/Proposal/policy (proposal creation)/illegal/invalid proposal status/Finished/proposal,34052826,101718,2040
|
||||
Agora/Proposal/policy (proposal creation)/illegal/invalid proposal status/Finished/stake,285591523,773491,8105
|
||||
Agora/Proposal/validator/cosignature/legal/with 1 cosigners: proposal,215479714,616586,11643
|
||||
Agora/Proposal/validator/cosignature/legal/with 5 cosigners: proposal,517656416,1429318,13008
|
||||
Agora/Proposal/validator/cosignature/legal/with 10 cosigners: proposal,999034382,2685005,14715
|
||||
Agora/Proposal/validator/voting/legal/different number of stakes/1 stakes/by owner/proposal,212972337,610304,11838
|
||||
Agora/Proposal/validator/voting/legal/different number of stakes/1 stakes/by owner/stake,250511654,706369,7814
|
||||
Agora/Proposal/validator/voting/legal/different number of stakes/1 stakes/by delegatee/proposal,212972337,610304,11838
|
||||
Agora/Proposal/validator/voting/legal/different number of stakes/1 stakes/by delegatee/stake,256935993,722124,7814
|
||||
Agora/Proposal/validator/voting/legal/different number of stakes/3 stakes/by owner/proposal,315681431,900960,13053
|
||||
Agora/Proposal/validator/voting/legal/different number of stakes/3 stakes/by owner/stake,498721508,1361509,9029
|
||||
Agora/Proposal/validator/voting/legal/different number of stakes/3 stakes/by delegatee/proposal,315681431,900960,13053
|
||||
Agora/Proposal/validator/voting/legal/different number of stakes/3 stakes/by delegatee/stake,505145847,1377264,9029
|
||||
Agora/Proposal/validator/voting/legal/different number of stakes/5 stakes/by owner/proposal,418390525,1191616,14268
|
||||
Agora/Proposal/validator/voting/legal/different number of stakes/5 stakes/by owner/stake,746931362,2016649,10244
|
||||
Agora/Proposal/validator/voting/legal/different number of stakes/5 stakes/by delegatee/proposal,418390525,1191616,14268
|
||||
Agora/Proposal/validator/voting/legal/different number of stakes/5 stakes/by delegatee/stake,753355701,2032404,10244
|
||||
Agora/Proposal/validator/voting/legal/different number of stakes/7 stakes/by owner/proposal,521099619,1482272,15482
|
||||
Agora/Proposal/validator/voting/legal/different number of stakes/7 stakes/by owner/stake,995141216,2671789,11458
|
||||
Agora/Proposal/validator/voting/legal/different number of stakes/7 stakes/by delegatee/proposal,521099619,1482272,15482
|
||||
Agora/Proposal/validator/voting/legal/different number of stakes/7 stakes/by delegatee/stake,1001565555,2687544,11458
|
||||
Agora/Proposal/validator/voting/legal/different number of stakes/9 stakes/by owner/proposal,623808713,1772928,16697
|
||||
Agora/Proposal/validator/voting/legal/different number of stakes/9 stakes/by owner/stake,1243351070,3326929,12673
|
||||
Agora/Proposal/validator/voting/legal/different number of stakes/9 stakes/by delegatee/proposal,623808713,1772928,16697
|
||||
Agora/Proposal/validator/voting/legal/different number of stakes/9 stakes/by delegatee/stake,1249775409,3342684,12673
|
||||
Agora/Proposal/validator/voting/legal/transparent non-GT tokens/proposal,212972337,610304,11838
|
||||
Agora/Proposal/validator/voting/legal/transparent non-GT tokens/stake,250511654,706369,7814
|
||||
Agora/Proposal/validator/voting/illegal/vote for nonexistent outcome/stake,250511654,706369,7819
|
||||
Agora/Proposal/validator/voting/illegal/unauthorized tx/proposal,212972337,610304,11838
|
||||
Agora/Proposal/validator/voting/illegal/more than one proposals/stake,250511654,706369,7819
|
||||
Agora/Proposal/validator/voting/illegal/locks not added/proposal,418390525,1191616,14237
|
||||
Agora/Proposal/validator/voting/illegal/attempt to burn stakes/proposal,395323670,1139996,13209
|
||||
Agora/Proposal/validator/voting/illegal/insufficient staked amount/stake,250511654,706369,7791
|
||||
Agora/Proposal/validator/voting/illegal/insufficient staked amount/stake,746931362,2016649,10156
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Draft to VotingReady/proposal,241684860,684071,12452
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from VotingReady to Locked/proposal,222017687,620605,12215
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Locked to Finished/proposal,236122351,649347,13482
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Locked to Finished/governor,397042799,1075492,12619
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Locked to Finished/authority,15755485,47872,3299
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Draft to VotingReady/proposal,237873570,671843,12173
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from VotingReady to Locked/proposal,218206397,608377,11936
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Locked to Finished/proposal,232311061,637119,13024
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Locked to Finished/governor,394788221,1067986,12254
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to next state/from Locked to Finished/authority,80911114,217260,2934
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to failed state/from Draft to Finished/proposal,211887073,596166,12208
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to failed state/from VotingReady to Finished/proposal,210213089,586572,12209
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to failed state/from Locked to Finished/proposal,223101034,618978,12209
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to failed state/from Draft to Finished/proposal,208075783,583938,11929
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to failed state/from VotingReady to Finished/proposal,206401799,574344,11930
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/legal/to failed state/from Locked to Finished/proposal,219289744,606750,11930
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/advance finished proposals/(negative test)/authority,15755485,47872,3299
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/advance finished proposals/(negative test)/authority,80911114,217260,2934
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/to next state too late/from Locked/governor,397042799,1075492,12619
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/to next state too late/from Locked/authority,15755485,47872,3299
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/to next state too late/from Locked/governor,394788221,1067986,12254
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/to next state too late/from Locked/authority,80911114,217260,2934
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/forget to mint GATs/proposal,232311061,637119,12378
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/mint GATs for wrong validators/proposal,232311061,637119,13024
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/mint GATs for wrong validators/authority,80911114,217260,2934
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/mint GATs with bad token name/proposal,232311061,637119,13056
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/mint GATs with bad token name/authority,12079326,37748,2966
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/wrong GAT datum/proposal,232311061,637119,13018
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/wrong GAT datum/authority,80911114,217260,2928
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/invalid governor output datum/proposal,232311061,637119,13024
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 1 effects/illegal/invalid governor output datum/authority,80911114,217260,2934
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Draft to VotingReady/proposal,315909580,888373,13368
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from VotingReady to Locked/proposal,299937293,834895,13131
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Locked to Finished/proposal,310347071,853649,14398
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Locked to Finished/governor,438778027,1192724,13230
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Locked to Finished/authority,15755485,47872,3910
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Draft to VotingReady/proposal,308287000,863917,12807
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from VotingReady to Locked/proposal,292314713,810439,12570
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Locked to Finished/proposal,302724491,829193,13659
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Locked to Finished/governor,434768836,1179104,12678
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to next state/from Locked to Finished/authority,80911114,217260,3358
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to failed state/from Draft to Finished/proposal,286111793,800468,13124
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to failed state/from VotingReady to Finished/proposal,284437809,790874,13125
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to failed state/from Locked to Finished/proposal,297325754,823280,13125
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to failed state/from Draft to Finished/proposal,278489213,776012,12563
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to failed state/from VotingReady to Finished/proposal,276815229,766418,12564
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/legal/to failed state/from Locked to Finished/proposal,289703174,798824,12564
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/advance finished proposals/(negative test)/authority,15755485,47872,3910
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/advance finished proposals/(negative test)/authority,80911114,217260,3358
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/to next state too late/from Locked/governor,438778027,1192724,13230
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/to next state too late/from Locked/authority,15755485,47872,3910
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/to next state too late/from Locked/governor,434768836,1179104,12678
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/to next state too late/from Locked/authority,80911114,217260,3358
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/forget to mint GATs/proposal,302724491,829193,13013
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/mint GATs for wrong validators/proposal,302724491,829193,13659
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/mint GATs for wrong validators/authority,80911114,217260,3358
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/mint GATs with bad token name/proposal,302724491,829193,13691
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/mint GATs with bad token name/authority,12079326,37748,3390
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/wrong GAT datum/proposal,302724491,829193,13653
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/wrong GAT datum/authority,80911114,217260,3352
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/invalid governor output datum/proposal,302724491,829193,13659
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 2 effects/illegal/invalid governor output datum/authority,80911114,217260,3358
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Draft to VotingReady/proposal,538583740,1501279,16115
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from VotingReady to Locked/proposal,533696111,1477765,15878
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Locked to Finished/proposal,533021231,1466555,17145
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Locked to Finished/governor,563983711,1544420,15061
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Locked to Finished/authority,15755485,47872,5741
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Draft to VotingReady/proposal,519527290,1440139,14714
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from VotingReady to Locked/proposal,514639661,1416625,14477
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Locked to Finished/proposal,513964781,1405415,15566
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Locked to Finished/governor,554710681,1512458,13949
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to next state/from Locked to Finished/authority,80911114,217260,4629
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to failed state/from Draft to Finished/proposal,508785953,1413374,15871
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to failed state/from VotingReady to Finished/proposal,507111969,1403780,15872
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to failed state/from Locked to Finished/proposal,519999914,1436186,15872
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to failed state/from Draft to Finished/proposal,489729503,1352234,14470
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to failed state/from VotingReady to Finished/proposal,488055519,1342640,14471
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/legal/to failed state/from Locked to Finished/proposal,500943464,1375046,14471
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/advance finished proposals/(negative test)/authority,15755485,47872,5741
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/advance finished proposals/(negative test)/authority,80911114,217260,4629
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/to next state too late/from Locked/governor,563983711,1544420,15061
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/to next state too late/from Locked/authority,15755485,47872,5741
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/to next state too late/from Locked/governor,554710681,1512458,13949
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/to next state too late/from Locked/authority,80911114,217260,4629
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/forget to mint GATs/proposal,513964781,1405415,14920
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/mint GATs for wrong validators/proposal,513964781,1405415,15566
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/mint GATs for wrong validators/authority,80911114,217260,4629
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/mint GATs with bad token name/proposal,513964781,1405415,15598
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/mint GATs with bad token name/authority,12079326,37748,4661
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/wrong GAT datum/proposal,513964781,1405415,15560
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/wrong GAT datum/authority,80911114,217260,4623
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/invalid governor output datum/proposal,513964781,1405415,15566
|
||||
Agora/Proposal/validator/advancing/with 1 cosigners and 5 effects/illegal/invalid governor output datum/authority,80911114,217260,4629
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Draft to VotingReady/proposal,417970750,1190555,13953
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from VotingReady to Locked/proposal,252368407,704333,12625
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Locked to Finished/proposal,266473071,733075,13892
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Locked to Finished/governor,411916095,1117356,12892
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Locked to Finished/authority,15755485,47872,3572
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Draft to VotingReady/proposal,414159460,1178327,13672
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from VotingReady to Locked/proposal,248557117,692105,12345
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Locked to Finished/proposal,262661781,720847,13433
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Locked to Finished/governor,409661517,1109850,12527
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to next state/from Locked to Finished/authority,80911114,217260,3207
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to failed state/from Draft to Finished/proposal,242237793,679894,12618
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to failed state/from VotingReady to Finished/proposal,240563809,670300,12619
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to failed state/from Locked to Finished/proposal,253451754,702706,12619
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to failed state/from Draft to Finished/proposal,238426503,667666,12338
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to failed state/from VotingReady to Finished/proposal,236752519,658072,12339
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/legal/to failed state/from Locked to Finished/proposal,249640464,690478,12339
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/advance finished proposals/(negative test)/authority,15755485,47872,3572
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/advance finished proposals/(negative test)/authority,80911114,217260,3207
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/to next state too late/from Locked/governor,411916095,1117356,12892
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/to next state too late/from Locked/authority,15755485,47872,3572
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/to next state too late/from Locked/governor,409661517,1109850,12527
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/to next state too late/from Locked/authority,80911114,217260,3207
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/forget to mint GATs/proposal,262661781,720847,12787
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/mint GATs for wrong validators/proposal,262661781,720847,13433
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/mint GATs for wrong validators/authority,80911114,217260,3207
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/mint GATs with bad token name/proposal,262661781,720847,13465
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/mint GATs with bad token name/authority,12079326,37748,3239
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/wrong GAT datum/proposal,262661781,720847,13427
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/wrong GAT datum/authority,80911114,217260,3201
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/invalid governor output datum/proposal,262661781,720847,13433
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 1 effects/illegal/invalid governor output datum/authority,80911114,217260,3207
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Draft to VotingReady/proposal,492195470,1394857,14868
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from VotingReady to Locked/proposal,330288013,918623,13541
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Locked to Finished/proposal,340697791,937377,14808
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Locked to Finished/governor,453651323,1234588,13503
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Locked to Finished/authority,15755485,47872,4183
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Draft to VotingReady/proposal,484572890,1370401,14308
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from VotingReady to Locked/proposal,322665433,894167,12980
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Locked to Finished/proposal,333075211,912921,14069
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Locked to Finished/governor,449642132,1220968,12951
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to next state/from Locked to Finished/authority,80911114,217260,3631
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to failed state/from Draft to Finished/proposal,316462513,884196,13534
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to failed state/from VotingReady to Finished/proposal,314788529,874602,13535
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to failed state/from Locked to Finished/proposal,327676474,907008,13535
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to failed state/from Draft to Finished/proposal,308839933,859740,12973
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to failed state/from VotingReady to Finished/proposal,307165949,850146,12974
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/legal/to failed state/from Locked to Finished/proposal,320053894,882552,12974
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/advance finished proposals/(negative test)/authority,15755485,47872,4183
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/advance finished proposals/(negative test)/authority,80911114,217260,3631
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/to next state too late/from Locked/governor,453651323,1234588,13503
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/to next state too late/from Locked/authority,15755485,47872,4183
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/to next state too late/from Locked/governor,449642132,1220968,12951
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/to next state too late/from Locked/authority,80911114,217260,3631
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/forget to mint GATs/proposal,333075211,912921,13423
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/mint GATs for wrong validators/proposal,333075211,912921,14069
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/mint GATs for wrong validators/authority,80911114,217260,3631
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/mint GATs with bad token name/proposal,333075211,912921,14101
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/mint GATs with bad token name/authority,12079326,37748,3663
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/wrong GAT datum/proposal,333075211,912921,14063
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/wrong GAT datum/authority,80911114,217260,3625
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/invalid governor output datum/proposal,333075211,912921,14069
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 2 effects/illegal/invalid governor output datum/authority,80911114,217260,3631
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Draft to VotingReady/proposal,714869630,2007763,17614
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from VotingReady to Locked/proposal,564046831,1561493,16287
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Locked to Finished/proposal,563371951,1550283,17554
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Locked to Finished/governor,578857007,1586284,15334
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Locked to Finished/authority,15755485,47872,6014
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Draft to VotingReady/proposal,695813180,1946623,16214
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from VotingReady to Locked/proposal,544990381,1500353,14886
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Locked to Finished/proposal,544315501,1489143,15975
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Locked to Finished/governor,569583977,1554322,14222
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to next state/from Locked to Finished/authority,80911114,217260,4902
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to failed state/from Draft to Finished/proposal,539136673,1497102,16280
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to failed state/from VotingReady to Finished/proposal,537462689,1487508,16281
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to failed state/from Locked to Finished/proposal,550350634,1519914,16281
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to failed state/from Draft to Finished/proposal,520080223,1435962,14879
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to failed state/from VotingReady to Finished/proposal,518406239,1426368,14880
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/legal/to failed state/from Locked to Finished/proposal,531294184,1458774,14880
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/advance finished proposals/(negative test)/authority,15755485,47872,6014
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/advance finished proposals/(negative test)/authority,80911114,217260,4902
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/to next state too late/from Locked/governor,578857007,1586284,15334
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/to next state too late/from Locked/authority,15755485,47872,6014
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/to next state too late/from Locked/governor,569583977,1554322,14222
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/to next state too late/from Locked/authority,80911114,217260,4902
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/forget to mint GATs/proposal,544315501,1489143,15329
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/mint GATs for wrong validators/proposal,544315501,1489143,15975
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/mint GATs for wrong validators/authority,80911114,217260,4902
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/mint GATs with bad token name/proposal,544315501,1489143,16007
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/mint GATs with bad token name/authority,12079326,37748,4934
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/wrong GAT datum/proposal,544315501,1489143,15969
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/wrong GAT datum/authority,80911114,217260,4896
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/invalid governor output datum/proposal,544315501,1489143,15975
|
||||
Agora/Proposal/validator/advancing/with 5 cosigners and 5 effects/illegal/invalid governor output datum/authority,80911114,217260,4902
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Draft to VotingReady/proposal,653491556,1869351,15829
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from VotingReady to Locked/proposal,290306807,808993,13137
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Locked to Finished/proposal,304411471,837735,14404
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Locked to Finished/governor,430507715,1169686,13234
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Locked to Finished/authority,15755485,47872,3914
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Draft to VotingReady/proposal,649680266,1857123,15550
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from VotingReady to Locked/proposal,286495517,796765,12857
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Locked to Finished/proposal,300600181,825507,13945
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Locked to Finished/governor,428253137,1162180,12868
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to next state/from Locked to Finished/authority,80911114,217260,3548
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to failed state/from Draft to Finished/proposal,280176193,784554,13130
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to failed state/from VotingReady to Finished/proposal,278502209,774960,13131
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to failed state/from Locked to Finished/proposal,291390154,807366,13131
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to failed state/from Draft to Finished/proposal,276364903,772326,12850
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to failed state/from VotingReady to Finished/proposal,274690919,762732,12851
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/legal/to failed state/from Locked to Finished/proposal,287578864,795138,12851
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/advance finished proposals/(negative test)/authority,15755485,47872,3914
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/advance finished proposals/(negative test)/authority,80911114,217260,3548
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/to next state too late/from Locked/governor,430507715,1169686,13234
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/to next state too late/from Locked/authority,15755485,47872,3914
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/to next state too late/from Locked/governor,428253137,1162180,12868
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/to next state too late/from Locked/authority,80911114,217260,3548
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/forget to mint GATs/proposal,300600181,825507,13300
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/mint GATs for wrong validators/proposal,300600181,825507,13945
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/mint GATs for wrong validators/authority,80911114,217260,3548
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/mint GATs with bad token name/proposal,300600181,825507,13977
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/mint GATs with bad token name/authority,12079326,37748,3580
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/wrong GAT datum/proposal,300600181,825507,13939
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/wrong GAT datum/authority,80911114,217260,3542
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/invalid governor output datum/proposal,300600181,825507,13945
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 1 effects/illegal/invalid governor output datum/authority,80911114,217260,3548
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Draft to VotingReady/proposal,727716276,2073653,16745
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from VotingReady to Locked/proposal,368226413,1023283,14052
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Locked to Finished/proposal,378636191,1042037,15319
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Locked to Finished/governor,472242943,1286918,13844
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Locked to Finished/authority,15755485,47872,4524
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Draft to VotingReady/proposal,720093696,2049197,16185
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from VotingReady to Locked/proposal,360603833,998827,13493
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Locked to Finished/proposal,371013611,1017581,14581
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Locked to Finished/governor,468233752,1273298,13292
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to next state/from Locked to Finished/authority,80911114,217260,3972
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to failed state/from Draft to Finished/proposal,354400913,988856,14045
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to failed state/from VotingReady to Finished/proposal,352726929,979262,14046
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to failed state/from Locked to Finished/proposal,365614874,1011668,14046
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to failed state/from Draft to Finished/proposal,346778333,964400,13486
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to failed state/from VotingReady to Finished/proposal,345104349,954806,13487
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/legal/to failed state/from Locked to Finished/proposal,357992294,987212,13487
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/advance finished proposals/(negative test)/authority,15755485,47872,4524
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/advance finished proposals/(negative test)/authority,80911114,217260,3972
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/to next state too late/from Locked/governor,472242943,1286918,13844
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/to next state too late/from Locked/authority,15755485,47872,4524
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/to next state too late/from Locked/governor,468233752,1273298,13292
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/to next state too late/from Locked/authority,80911114,217260,3972
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/forget to mint GATs/proposal,371013611,1017581,13935
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/mint GATs for wrong validators/proposal,371013611,1017581,14581
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/mint GATs for wrong validators/authority,80911114,217260,3972
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/mint GATs with bad token name/proposal,371013611,1017581,14613
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/mint GATs with bad token name/authority,12079326,37748,4004
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/wrong GAT datum/proposal,371013611,1017581,14575
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/wrong GAT datum/authority,80911114,217260,3966
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/invalid governor output datum/proposal,371013611,1017581,14581
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 2 effects/illegal/invalid governor output datum/authority,80911114,217260,3972
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Draft to VotingReady/proposal,950390436,2686559,19492
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from VotingReady to Locked/proposal,601985231,1666153,16799
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Locked to Finished/proposal,601310351,1654943,18066
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Locked to Finished/governor,597448627,1638614,15675
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Locked to Finished/authority,15755485,47872,6355
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Draft to VotingReady/proposal,931333986,2625419,18091
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from VotingReady to Locked/proposal,582928781,1605013,15399
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Locked to Finished/proposal,582253901,1593803,16487
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Locked to Finished/governor,588175597,1606652,14563
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to next state/from Locked to Finished/authority,80911114,217260,5243
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to failed state/from Draft to Finished/proposal,577075073,1601762,16792
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to failed state/from VotingReady to Finished/proposal,575401089,1592168,16793
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to failed state/from Locked to Finished/proposal,588289034,1624574,16793
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to failed state/from Draft to Finished/proposal,558018623,1540622,15392
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to failed state/from VotingReady to Finished/proposal,556344639,1531028,15393
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/legal/to failed state/from Locked to Finished/proposal,569232584,1563434,15393
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/advance finished proposals/(negative test)/authority,15755485,47872,6355
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/advance finished proposals/(negative test)/authority,80911114,217260,5243
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/to next state too late/from Locked/governor,597448627,1638614,15675
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/to next state too late/from Locked/authority,15755485,47872,6355
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/to next state too late/from Locked/governor,588175597,1606652,14563
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/to next state too late/from Locked/authority,80911114,217260,5243
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/forget to mint GATs/proposal,582253901,1593803,15841
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/mint GATs for wrong validators/proposal,582253901,1593803,16487
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/mint GATs for wrong validators/authority,80911114,217260,5243
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/mint GATs with bad token name/proposal,582253901,1593803,16519
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/mint GATs with bad token name/authority,12079326,37748,5275
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/wrong GAT datum/proposal,582253901,1593803,16481
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/wrong GAT datum/authority,80911114,217260,5237
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/invalid governor output datum/proposal,582253901,1593803,16487
|
||||
Agora/Proposal/validator/advancing/with 10 cosigners and 5 effects/illegal/invalid governor output datum/authority,80911114,217260,5243
|
||||
Agora/Proposal/validator/unlocking/legal/with 1 stakes/voter: retract votes while voting/stake,261437934,715948,8036
|
||||
Agora/Proposal/validator/unlocking/legal/with 1 stakes/voter: retract votes while voting/proposal,210078186,594774,12065
|
||||
Agora/Proposal/validator/unlocking/legal/with 1 stakes/voter: retract votes while voting by delegatee/stake,267862273,731703,8036
|
||||
Agora/Proposal/validator/unlocking/legal/with 1 stakes/voter: retract votes while voting by delegatee/proposal,210078186,594774,12065
|
||||
Agora/Proposal/validator/unlocking/legal/with 1 stakes/voter/creator: retract votes while voting/stake,270958650,743485,8052
|
||||
Agora/Proposal/validator/unlocking/legal/with 1 stakes/voter/creator: retract votes while voting/proposal,216873590,615188,12076
|
||||
Agora/Proposal/validator/unlocking/legal/with 1 stakes/creator: remove creator lock after voting/stake,261933191,716955,8039
|
||||
Agora/Proposal/validator/unlocking/legal/with 1 stakes/creator: remove creator lock after voting/proposal,181968899,516983,12069
|
||||
Agora/Proposal/validator/unlocking/legal/with 1 stakes/Voter: remove lock after voting/stake,262568912,718352,8041
|
||||
Agora/Proposal/validator/unlocking/legal/with 1 stakes/Voter: remove lock after voting/proposal,183007176,519781,12070
|
||||
Agora/Proposal/validator/unlocking/legal/with 3 stakes/voter: retract votes while voting/stake,530554502,1381974,9381
|
||||
Agora/Proposal/validator/unlocking/legal/with 3 stakes/voter: retract votes while voting/proposal,316741456,889978,13410
|
||||
Agora/Proposal/validator/unlocking/legal/with 3 stakes/voter: retract votes while voting by delegatee/stake,536978841,1397729,9381
|
||||
Agora/Proposal/validator/unlocking/legal/with 3 stakes/voter: retract votes while voting by delegatee/proposal,316741456,889978,13410
|
||||
Agora/Proposal/validator/unlocking/legal/with 3 stakes/voter/creator: retract votes while voting/stake,559116650,1464585,9419
|
||||
Agora/Proposal/validator/unlocking/legal/with 3 stakes/voter/creator: retract votes while voting/proposal,337127668,951220,13443
|
||||
Agora/Proposal/validator/unlocking/legal/with 3 stakes/creator: remove creator lock after voting/stake,529778317,1380187,9382
|
||||
Agora/Proposal/validator/unlocking/legal/with 3 stakes/creator: remove creator lock after voting/proposal,247894061,696527,13412
|
||||
Agora/Proposal/validator/unlocking/legal/with 3 stakes/Voter: remove lock after voting/stake,531685480,1384378,9386
|
||||
Agora/Proposal/validator/unlocking/legal/with 3 stakes/Voter: remove lock after voting/proposal,251008892,704921,13415
|
||||
Agora/Proposal/validator/unlocking/legal/with 5 stakes/voter: retract votes while voting/stake,819317726,2079440,10727
|
||||
Agora/Proposal/validator/unlocking/legal/with 5 stakes/voter: retract votes while voting/proposal,423404726,1185182,14756
|
||||
Agora/Proposal/validator/unlocking/legal/with 5 stakes/voter: retract votes while voting by delegatee/stake,825742065,2095195,10727
|
||||
Agora/Proposal/validator/unlocking/legal/with 5 stakes/voter: retract votes while voting by delegatee/proposal,423404726,1185182,14756
|
||||
Agora/Proposal/validator/unlocking/legal/with 5 stakes/voter/creator: retract votes while voting/stake,866921306,2217125,10787
|
||||
Agora/Proposal/validator/unlocking/legal/with 5 stakes/voter/creator: retract votes while voting/proposal,457381746,1287252,14811
|
||||
Agora/Proposal/validator/unlocking/legal/with 5 stakes/creator: remove creator lock after voting/stake,817270099,2074859,10726
|
||||
Agora/Proposal/validator/unlocking/legal/with 5 stakes/creator: remove creator lock after voting/proposal,313819223,876071,14756
|
||||
Agora/Proposal/validator/unlocking/legal/with 5 stakes/Voter: remove lock after voting/stake,820448704,2081844,10732
|
||||
Agora/Proposal/validator/unlocking/legal/with 5 stakes/Voter: remove lock after voting/proposal,319010608,890061,14761
|
||||
Agora/Proposal/validator/unlocking/legal/with 7 stakes/voter: retract votes while voting/stake,1127727606,2808346,12072
|
||||
Agora/Proposal/validator/unlocking/legal/with 7 stakes/voter: retract votes while voting/proposal,530067996,1480386,16101
|
||||
Agora/Proposal/validator/unlocking/legal/with 7 stakes/voter: retract votes while voting by delegatee/stake,1134151945,2824101,12072
|
||||
Agora/Proposal/validator/unlocking/legal/with 7 stakes/voter: retract votes while voting by delegatee/proposal,530067996,1480386,16101
|
||||
Agora/Proposal/validator/unlocking/legal/with 7 stakes/voter/creator: retract votes while voting/stake,1194372618,3001105,12154
|
||||
Agora/Proposal/validator/unlocking/legal/with 7 stakes/voter/creator: retract votes while voting/proposal,577635824,1623284,16178
|
||||
Agora/Proposal/validator/unlocking/legal/with 7 stakes/creator: remove creator lock after voting/stake,1124408537,2800971,12069
|
||||
Agora/Proposal/validator/unlocking/legal/with 7 stakes/creator: remove creator lock after voting/proposal,379744385,1055615,16099
|
||||
Agora/Proposal/validator/unlocking/legal/with 7 stakes/Voter: remove lock after voting/stake,1128858584,2810750,12077
|
||||
Agora/Proposal/validator/unlocking/legal/with 7 stakes/Voter: remove lock after voting/proposal,387012324,1075201,16106
|
||||
Agora/Proposal/validator/unlocking/legal/with 9 stakes/voter: retract votes while voting/stake,1455784142,3568692,13417
|
||||
Agora/Proposal/validator/unlocking/legal/with 9 stakes/voter: retract votes while voting/proposal,636731266,1775590,17446
|
||||
Agora/Proposal/validator/unlocking/legal/with 9 stakes/voter: retract votes while voting by delegatee/stake,1462208481,3584447,13417
|
||||
Agora/Proposal/validator/unlocking/legal/with 9 stakes/voter: retract votes while voting by delegatee/proposal,636731266,1775590,17446
|
||||
Agora/Proposal/validator/unlocking/legal/with 9 stakes/voter/creator: retract votes while voting/stake,1541470586,3816525,13521
|
||||
Agora/Proposal/validator/unlocking/legal/with 9 stakes/voter/creator: retract votes while voting/proposal,697889902,1959316,17545
|
||||
Agora/Proposal/validator/unlocking/legal/with 9 stakes/creator: remove creator lock after voting/stake,1451193631,3558523,13412
|
||||
Agora/Proposal/validator/unlocking/legal/with 9 stakes/creator: remove creator lock after voting/proposal,445669547,1235159,17442
|
||||
Agora/Proposal/validator/unlocking/legal/with 9 stakes/Voter: remove lock after voting/stake,1456915120,3571096,13422
|
||||
Agora/Proposal/validator/unlocking/legal/with 9 stakes/Voter: remove lock after voting/proposal,455014040,1260341,17451
|
||||
Agora/Proposal/validator/unlocking/legal/with 11 stakes/voter: retract votes while voting/stake,1803487334,4360478,14763
|
||||
Agora/Proposal/validator/unlocking/legal/with 11 stakes/voter: retract votes while voting/proposal,743394536,2070794,18792
|
||||
Agora/Proposal/validator/unlocking/legal/with 11 stakes/voter: retract votes while voting by delegatee/stake,1809911673,4376233,14763
|
||||
Agora/Proposal/validator/unlocking/legal/with 11 stakes/voter: retract votes while voting by delegatee/proposal,743394536,2070794,18792
|
||||
Agora/Proposal/validator/unlocking/legal/with 11 stakes/voter/creator: retract votes while voting/stake,1908215210,4663385,14890
|
||||
Agora/Proposal/validator/unlocking/legal/with 11 stakes/voter/creator: retract votes while voting/proposal,818143980,2295348,18914
|
||||
Agora/Proposal/validator/unlocking/legal/with 11 stakes/creator: remove creator lock after voting/stake,1797625381,4347515,14756
|
||||
Agora/Proposal/validator/unlocking/legal/with 11 stakes/creator: remove creator lock after voting/proposal,511594709,1414703,18786
|
||||
Agora/Proposal/validator/unlocking/legal/with 11 stakes/Voter: remove lock after voting/stake,1804618312,4362882,14768
|
||||
Agora/Proposal/validator/unlocking/legal/with 11 stakes/Voter: remove lock after voting/proposal,523015756,1445481,18797
|
||||
Agora/Proposal/validator/unlocking/illegal/with 1 stakes/retract votes while not voting/(negative test)/stake,260872445,714746,8036
|
||||
Agora/Proposal/validator/unlocking/illegal/with 1 stakes/retract votes while not voting/(negative test)/stake,262003423,717150,8036
|
||||
Agora/Proposal/validator/unlocking/illegal/with 1 stakes/retract votes while not voting/(negative test)/stake,262568912,718352,8036
|
||||
Agora/Proposal/validator/unlocking/illegal/with 1 stakes/remove creator too early/(negative test)/proposal,180272432,513377,12069
|
||||
Agora/Proposal/validator/unlocking/illegal/with 1 stakes/remove creator too early/(negative test)/proposal,184477283,524638,12069
|
||||
Agora/Proposal/validator/unlocking/illegal/with 1 stakes/remove creator too early/(negative test)/proposal,181403410,515781,12069
|
||||
Agora/Proposal/validator/unlocking/illegal/with 1 stakes/unlock an irrelevant stake/stake,270536932,747909,8058
|
||||
Agora/Proposal/validator/unlocking/illegal/with 1 stakes/creator: retract votes/stake,258799749,715312,8040
|
||||
Agora/Proposal/validator/unlocking/illegal/with 1 stakes/change output stake value/proposal,210078186,594774,12062
|
||||
Agora/Proposal/validator/unlocking/illegal/with 3 stakes/retract votes while not voting/(negative test)/stake,529989013,1380772,9381
|
||||
Agora/Proposal/validator/unlocking/illegal/with 3 stakes/retract votes while not voting/(negative test)/stake,531119991,1383176,9381
|
||||
Agora/Proposal/validator/unlocking/illegal/with 3 stakes/retract votes while not voting/(negative test)/stake,531685480,1384378,9381
|
||||
Agora/Proposal/validator/unlocking/illegal/with 3 stakes/remove creator too early/(negative test)/proposal,246197594,692921,13412
|
||||
Agora/Proposal/validator/unlocking/illegal/with 3 stakes/remove creator too early/(negative test)/proposal,250402445,704182,13412
|
||||
Agora/Proposal/validator/unlocking/illegal/with 3 stakes/remove creator too early/(negative test)/proposal,247328572,695325,13412
|
||||
Agora/Proposal/validator/unlocking/illegal/with 3 stakes/unlock an irrelevant stake/stake,543116504,1454277,9437
|
||||
Agora/Proposal/validator/unlocking/illegal/with 3 stakes/creator: retract votes/stake,507904955,1356486,9395
|
||||
Agora/Proposal/validator/unlocking/illegal/with 3 stakes/change output stake value/proposal,316741456,889978,13401
|
||||
Agora/Proposal/validator/unlocking/illegal/with 5 stakes/retract votes while not voting/(negative test)/stake,818752237,2078238,10727
|
||||
Agora/Proposal/validator/unlocking/illegal/with 5 stakes/retract votes while not voting/(negative test)/stake,819883215,2080642,10727
|
||||
Agora/Proposal/validator/unlocking/illegal/with 5 stakes/retract votes while not voting/(negative test)/stake,820448704,2081844,10727
|
||||
Agora/Proposal/validator/unlocking/illegal/with 5 stakes/remove creator too early/(negative test)/proposal,312122756,872465,14756
|
||||
Agora/Proposal/validator/unlocking/illegal/with 5 stakes/remove creator too early/(negative test)/proposal,316327607,883726,14756
|
||||
Agora/Proposal/validator/unlocking/illegal/with 5 stakes/remove creator too early/(negative test)/proposal,313253734,874869,14756
|
||||
Agora/Proposal/validator/unlocking/illegal/with 5 stakes/unlock an irrelevant stake/stake,815696076,2160645,10817
|
||||
Agora/Proposal/validator/unlocking/illegal/with 5 stakes/creator: retract votes/stake,757010161,1997660,10751
|
||||
Agora/Proposal/validator/unlocking/illegal/with 5 stakes/change output stake value/proposal,423404726,1185182,14740
|
||||
Agora/Proposal/validator/unlocking/illegal/with 7 stakes/retract votes while not voting/(negative test)/stake,1127162117,2807144,12072
|
||||
Agora/Proposal/validator/unlocking/illegal/with 7 stakes/retract votes while not voting/(negative test)/stake,1128293095,2809548,12072
|
||||
Agora/Proposal/validator/unlocking/illegal/with 7 stakes/retract votes while not voting/(negative test)/stake,1128858584,2810750,12072
|
||||
Agora/Proposal/validator/unlocking/illegal/with 7 stakes/remove creator too early/(negative test)/proposal,378047918,1052009,16099
|
||||
Agora/Proposal/validator/unlocking/illegal/with 7 stakes/remove creator too early/(negative test)/proposal,382252769,1063270,16099
|
||||
Agora/Proposal/validator/unlocking/illegal/with 7 stakes/remove creator too early/(negative test)/proposal,379178896,1054413,16099
|
||||
Agora/Proposal/validator/unlocking/illegal/with 7 stakes/unlock an irrelevant stake/stake,1088275648,2867013,12196
|
||||
Agora/Proposal/validator/unlocking/illegal/with 7 stakes/creator: retract votes/stake,1006115367,2638834,12106
|
||||
Agora/Proposal/validator/unlocking/illegal/with 7 stakes/change output stake value/proposal,530067996,1480386,16080
|
||||
Agora/Proposal/validator/unlocking/illegal/with 9 stakes/retract votes while not voting/(negative test)/stake,1455218653,3567490,13417
|
||||
Agora/Proposal/validator/unlocking/illegal/with 9 stakes/retract votes while not voting/(negative test)/stake,1456349631,3569894,13417
|
||||
Agora/Proposal/validator/unlocking/illegal/with 9 stakes/retract votes while not voting/(negative test)/stake,1456915120,3571096,13417
|
||||
Agora/Proposal/validator/unlocking/illegal/with 9 stakes/remove creator too early/(negative test)/proposal,443973080,1231553,17442
|
||||
Agora/Proposal/validator/unlocking/illegal/with 9 stakes/remove creator too early/(negative test)/proposal,448177931,1242814,17442
|
||||
Agora/Proposal/validator/unlocking/illegal/with 9 stakes/remove creator too early/(negative test)/proposal,445104058,1233957,17442
|
||||
Agora/Proposal/validator/unlocking/illegal/with 9 stakes/unlock an irrelevant stake/stake,1360855220,3573381,13576
|
||||
Agora/Proposal/validator/unlocking/illegal/with 9 stakes/creator: retract votes/stake,1255220573,3280008,13461
|
||||
Agora/Proposal/validator/unlocking/illegal/with 9 stakes/change output stake value/proposal,636731266,1775590,17419
|
||||
Agora/Proposal/validator/unlocking/illegal/with 11 stakes/retract votes while not voting/(negative test)/stake,1802921845,4359276,14763
|
||||
Agora/Proposal/validator/unlocking/illegal/with 11 stakes/retract votes while not voting/(negative test)/stake,1804052823,4361680,14763
|
||||
Agora/Proposal/validator/unlocking/illegal/with 11 stakes/retract votes while not voting/(negative test)/stake,1804618312,4362882,14763
|
||||
Agora/Proposal/validator/unlocking/illegal/with 11 stakes/remove creator too early/(negative test)/proposal,509898242,1411097,18786
|
||||
Agora/Proposal/validator/unlocking/illegal/with 11 stakes/remove creator too early/(negative test)/proposal,514103093,1422358,18786
|
||||
Agora/Proposal/validator/unlocking/illegal/with 11 stakes/remove creator too early/(negative test)/proposal,511029220,1413501,18786
|
||||
Agora/Proposal/validator/unlocking/illegal/with 11 stakes/unlock an irrelevant stake/stake,1633434792,4279749,14956
|
||||
Agora/Proposal/validator/unlocking/illegal/with 11 stakes/creator: retract votes/stake,1504325779,3921182,14818
|
||||
Agora/Proposal/validator/unlocking/illegal/with 11 stakes/change output stake value/proposal,743394536,2070794,18759
|
||||
Agora/AuthorityToken/singleAuthorityTokenBurned/Correct simple,26456223,75851,755
|
||||
Agora/AuthorityToken/singleAuthorityTokenBurned/Correct many inputs,51581175,146321,855
|
||||
Agora/AuthorityToken/singleAuthorityTokenBurned/Correct even though scripts don't match,26456223,75851,754
|
||||
|
|
@ -478,5 +465,5 @@ Agora/Treasury/Validator/Positive/Fails when GAT token name is not script addres
|
|||
Agora/AuthorityToken/singleAuthorityTokenBurned/Correct simple,26456223,75851,755
|
||||
Agora/AuthorityToken/singleAuthorityTokenBurned/Correct many inputs,51581175,146321,855
|
||||
Agora/AuthorityToken/singleAuthorityTokenBurned/Correct even though scripts don't match,26456223,75851,754
|
||||
Agora/Governor/policy/totally legal,59844630,160840,2585
|
||||
Agora/Governor/validator/mutate/legal,124803201,345777,11001
|
||||
Agora/Governor/policy/totally legal,61478715,165435,2674
|
||||
Agora/Governor/validator/mutate/legal,126634074,350768,10968
|
||||
|
|
|
|||
|
12
flake.lock
generated
12
flake.lock
generated
|
|
@ -11460,11 +11460,11 @@
|
|||
"plutarch": "plutarch_6"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1663679353,
|
||||
"narHash": "sha256-CK+hgOoU9qARRnaUlxlh9ZBWb0G6d8F0VslAbXd8mIM=",
|
||||
"lastModified": 1664495234,
|
||||
"narHash": "sha256-GEl2kRkL3MdHL1fDKbur5VVThR/w082w7KccfDL42qg=",
|
||||
"owner": "Liqwid-Labs",
|
||||
"repo": "plutarch-context-builder",
|
||||
"rev": "3bc59acb11264c4fa43c95fa615a4dbf69e0f981",
|
||||
"rev": "9ea4dab758a4d60e69c794fe4e349ddabc8e7018",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -11979,17 +11979,17 @@
|
|||
"plutarch": "plutarch_15"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1664028810,
|
||||
"lastModified": 1664220695,
|
||||
"narHash": "sha256-thMEO1P/ciHjnMFyL0bla781TG5C/nB5EEtebb3Boik=",
|
||||
"owner": "Liqwid-Labs",
|
||||
"repo": "plutarch-script-export",
|
||||
"rev": "4f0da58ba67cdcfe5c7d97e6e27dc00dfb71e657",
|
||||
"rev": "eba175e63516a4fed43ceab1826ea6522f28dd0f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "Liqwid-Labs",
|
||||
"ref": "main",
|
||||
"repo": "plutarch-script-export",
|
||||
"rev": "4f0da58ba67cdcfe5c7d97e6e27dc00dfb71e657",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue