apply Emily's suggestions
This commit is contained in:
parent
701340688a
commit
8242330ac9
3 changed files with 334 additions and 328 deletions
|
|
@ -42,6 +42,7 @@ import Agora.Utils (
|
||||||
import Plutarch.Api.V1 (
|
import Plutarch.Api.V1 (
|
||||||
PDatumHash,
|
PDatumHash,
|
||||||
PMintingPolicy,
|
PMintingPolicy,
|
||||||
|
PPubKeyHash,
|
||||||
PScriptContext (PScriptContext),
|
PScriptContext (PScriptContext),
|
||||||
PScriptPurpose (PMinting, PSpending),
|
PScriptPurpose (PMinting, PSpending),
|
||||||
PTxInfo (PTxInfo),
|
PTxInfo (PTxInfo),
|
||||||
|
|
@ -305,198 +306,272 @@ proposalValidator proposal =
|
||||||
|
|
||||||
----------------------------------------------------------------------------
|
----------------------------------------------------------------------------
|
||||||
|
|
||||||
let acceptMultipleStakes = pmatch proposalRedeemer $ \case
|
withMultipleStakes' ::
|
||||||
PCosign _ -> pconstant True
|
Term
|
||||||
PAdvanceProposal _ ->
|
_
|
||||||
currentStatus #== pconstant Draft
|
( ( PInteger
|
||||||
_ -> pconstant False
|
:--> PBuiltinList (PAsData PPubKeyHash)
|
||||||
|
:--> PUnit
|
||||||
|
)
|
||||||
|
:--> PUnit
|
||||||
|
) <-
|
||||||
|
pletC $
|
||||||
|
plam $ \validationLogic -> unTermCont $ do
|
||||||
|
-- The following code ensures that all the stake datums are not
|
||||||
|
-- changed.
|
||||||
|
--
|
||||||
|
-- TODO: This is quite inefficient (O(nlogn)) but for now we don't
|
||||||
|
-- have a nice way to check this. In plutus v2 we'll have map of
|
||||||
|
-- (Script -> Redeemer) in ScriptContext, which should be the
|
||||||
|
-- straight up solution.
|
||||||
|
let sortDatumHashes = phoistAcyclic $ pmsortBy # pltAsData
|
||||||
|
|
||||||
|
sortedStakeInputDatumHashes =
|
||||||
|
sortDatumHashes # stakeInputDatumHashes
|
||||||
|
|
||||||
|
sortedStakeOutputDatumHashes =
|
||||||
|
sortDatumHashes # stakeOutputDatumHashes
|
||||||
|
|
||||||
|
pguardC "All stake datum are unchanged" $
|
||||||
|
plistEquals
|
||||||
|
# sortedStakeInputDatumHashes
|
||||||
|
# sortedStakeOutputDatumHashes
|
||||||
|
|
||||||
|
PPair totalStakedAmount stakeOwners <-
|
||||||
|
pmatchC $
|
||||||
|
pfoldl
|
||||||
|
# plam
|
||||||
|
( \l dh -> unTermCont $ do
|
||||||
|
let stake =
|
||||||
|
pfromData $
|
||||||
|
pfromJust
|
||||||
|
#$ ptryFindDatum
|
||||||
|
@(PAsData PStakeDatum)
|
||||||
|
# pfromData dh
|
||||||
|
# txInfoF.datums
|
||||||
|
|
||||||
|
stakeF <- pletFieldsC @'["stakedAmount", "owner"] stake
|
||||||
|
|
||||||
|
PPair amount owners <- pmatchC l
|
||||||
|
|
||||||
|
let newAmount = amount + punsafeCoerce (pfromData stakeF.stakedAmount)
|
||||||
|
updatedOwners = pcons # stakeF.owner # owners
|
||||||
|
|
||||||
|
pure $ pcon $ PPair newAmount updatedOwners
|
||||||
|
)
|
||||||
|
# pcon (PPair (0 :: Term _ PInteger) (pnil @PBuiltinList))
|
||||||
|
# stakeInputDatumHashes
|
||||||
|
|
||||||
|
sortedStakeOwners <- pletC $ pmsortBy # pltAsData # stakeOwners
|
||||||
|
|
||||||
|
pure $ validationLogic # totalStakedAmount # sortedStakeOwners
|
||||||
|
|
||||||
|
withSingleStake' ::
|
||||||
|
Term
|
||||||
|
_
|
||||||
|
( ( PStakeDatum :--> PStakeDatum :--> PBool :--> PUnit
|
||||||
|
)
|
||||||
|
:--> PUnit
|
||||||
|
) <- pletC $
|
||||||
|
plam $ \validationLogic -> unTermCont $ do
|
||||||
|
pguardC "Can only deal with one stake" $
|
||||||
|
stakeInputNum #== 1
|
||||||
|
|
||||||
|
stakeInputHash <- pletC $ pfromData $ phead # stakeInputDatumHashes
|
||||||
|
stakeOutputHash <- pletC $ pfromData $ phead # stakeOutputDatumHashes
|
||||||
|
|
||||||
|
stakeIn :: Term _ PStakeDatum <-
|
||||||
|
pletC $
|
||||||
|
pfromData $
|
||||||
|
pfromJust #$ ptryFindDatum # stakeInputHash # txInfoF.datums
|
||||||
|
|
||||||
|
stakeOut :: Term _ PStakeDatum <-
|
||||||
|
pletC $
|
||||||
|
pfromData $
|
||||||
|
pfromJust #$ ptryFindDatum # stakeOutputHash # txInfoF.datums
|
||||||
|
|
||||||
|
stakeUnchanged <- pletC $ stakeInputHash #== stakeOutputHash
|
||||||
|
|
||||||
|
pure $ validationLogic # stakeIn # stakeOut # stakeUnchanged
|
||||||
|
|
||||||
|
let withMultipleStakes val =
|
||||||
|
withMultipleStakes' #$ plam $
|
||||||
|
\totalStakedAmount
|
||||||
|
sortedStakeOwner ->
|
||||||
|
unTermCont $
|
||||||
|
val totalStakedAmount sortedStakeOwner
|
||||||
|
|
||||||
|
withSingleStake val =
|
||||||
|
withSingleStake' #$ plam $ \stakeIn stakeOut stakeUnchange -> unTermCont $ do
|
||||||
|
stakeInF <- pletFieldsC @'["stakedAmount", "lockedBy", "owner"] stakeIn
|
||||||
|
|
||||||
|
val stakeInF stakeOut stakeUnchange
|
||||||
|
|
||||||
pure $
|
pure $
|
||||||
popaque $
|
popaque $
|
||||||
pif
|
pmatch proposalRedeemer $ \case
|
||||||
acceptMultipleStakes
|
PCosign r -> withMultipleStakes $ \_ sortedStakeOwners -> do
|
||||||
( unTermCont $ do
|
pguardC "Should be in draft state" $
|
||||||
-- The following code ensures that all the stake datums are not
|
currentStatus #== pconstant Draft
|
||||||
-- changed.
|
|
||||||
--
|
|
||||||
-- TODO: This is quite inefficient (O(nlogn)) but for now we don't
|
|
||||||
-- have a nice way to check this. In plutus v2 we'll have map of
|
|
||||||
-- (Script -> Redeemer) in ScriptContext, which should be the
|
|
||||||
-- straight up solution.
|
|
||||||
let sortDatumHashes = phoistAcyclic $ pmsortBy # pltAsData
|
|
||||||
|
|
||||||
sortedStakeInputDatumHashes =
|
newSigs <- pletC $ pfield @"newCosigners" # r
|
||||||
sortDatumHashes # stakeInputDatumHashes
|
|
||||||
|
|
||||||
sortedStakeOutputDatumHashes =
|
pguardC "Signed by all new cosigners" $
|
||||||
sortDatumHashes # stakeOutputDatumHashes
|
pall # signedBy # newSigs
|
||||||
|
|
||||||
pguardC "All stake datum are unchanged" $
|
updatedSigs <-
|
||||||
plistEquals
|
pletC $
|
||||||
# sortedStakeInputDatumHashes
|
pmergeBy # pltAsData
|
||||||
# sortedStakeOutputDatumHashes
|
# newSigs
|
||||||
|
# proposalF.cosigners
|
||||||
|
|
||||||
PPair totalStakedAmount stakeOwners <-
|
pguardC "Cosigners are unique" $
|
||||||
pmatchC $
|
pisUniq' # updatedSigs
|
||||||
pfoldl
|
|
||||||
# plam
|
|
||||||
( \l dh -> unTermCont $ do
|
|
||||||
let stake =
|
|
||||||
pfromData $
|
|
||||||
pfromJust
|
|
||||||
#$ ptryFindDatum
|
|
||||||
@(PAsData PStakeDatum)
|
|
||||||
# pfromData dh
|
|
||||||
# txInfoF.datums
|
|
||||||
|
|
||||||
stakeF <- pletFieldsC @'["stakedAmount", "owner"] stake
|
pguardC "All new cosigners are witnessed by their Stake datums" $
|
||||||
|
plistEquals # sortedStakeOwners # newSigs
|
||||||
|
|
||||||
PPair amount owners <- pmatchC l
|
let expectedDatum =
|
||||||
|
mkRecordConstr
|
||||||
|
PProposalDatum
|
||||||
|
( #proposalId .= proposalF.proposalId
|
||||||
|
.& #effects .= proposalF.effects
|
||||||
|
.& #status .= proposalF.status
|
||||||
|
.& #cosigners .= pdata updatedSigs
|
||||||
|
.& #thresholds .= proposalF.thresholds
|
||||||
|
.& #votes .= proposalF.votes
|
||||||
|
.& #timingConfig .= proposalF.timingConfig
|
||||||
|
.& #startingTime .= proposalF.startingTime
|
||||||
|
)
|
||||||
|
|
||||||
let newAmount = amount + punsafeCoerce (pfromData stakeF.stakedAmount)
|
pguardC "Signatures are correctly added to cosignature list" $
|
||||||
updatedOwners = pcons # stakeF.owner # owners
|
proposalOut #== expectedDatum
|
||||||
|
|
||||||
pure $ pcon $ PPair newAmount updatedOwners
|
pure $ pconstant ()
|
||||||
)
|
|
||||||
# pcon (PPair (0 :: Term _ PInteger) (pnil @PBuiltinList))
|
|
||||||
# stakeInputDatumHashes
|
|
||||||
|
|
||||||
sortedStakeOwners <- pletC $ pmsortBy # pltAsData # stakeOwners
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
redeemer <- pmatchC proposalRedeemer
|
PVote r -> withSingleStake $ \stakeInF stakeOut _ -> do
|
||||||
|
pguardC "Input proposal must be in VotingReady state" $
|
||||||
|
currentStatus #== pconstant VotingReady
|
||||||
|
|
||||||
case redeemer of
|
pguardC "Proposal time should be wthin the voting period" $
|
||||||
PCosign r -> do
|
isVotingPeriod # proposalF.timingConfig
|
||||||
pguardC "Should be in draft state" $
|
# proposalF.startingTime
|
||||||
currentStatus #== pconstant Draft
|
# currentTime
|
||||||
|
|
||||||
newSigs <- pletC $ pfield @"newCosigners" # r
|
-- Ensure the transaction is voting to a valid 'ResultTag'(outcome).
|
||||||
|
PProposalVotes voteMap <- pmatchC proposalF.votes
|
||||||
|
voteFor <- pletC $ pfromData $ pfield @"resultTag" # r
|
||||||
|
|
||||||
pguardC "Signed by all new cosigners" $
|
pguardC "Vote option should be valid" $
|
||||||
pall # signedBy # newSigs
|
pisJust #$ plookup # voteFor # voteMap
|
||||||
|
|
||||||
updatedSigs <-
|
-- Ensure that no lock with the current proposal id has been put on the stake.
|
||||||
pletC $
|
pguardC "Same stake shouldn't vote on the same proposal twice" $
|
||||||
pmergeBy # pltAsData
|
pnot #$ pany
|
||||||
# newSigs
|
# plam
|
||||||
# proposalF.cosigners
|
( \((pfield @"proposalTag" #) . pfromData -> pid) ->
|
||||||
|
pid #== proposalF.proposalId
|
||||||
|
)
|
||||||
|
# pfromData stakeInF.lockedBy
|
||||||
|
|
||||||
pguardC "Cosigners are unique" $
|
let -- The amount of new votes should be the 'stakedAmount'.
|
||||||
pisUniq' # updatedSigs
|
-- Update the vote counter of the proposal, and leave other stuff as is.
|
||||||
|
expectedNewVotes = pmatch (pfromData proposalF.votes) $ \(PProposalVotes m) ->
|
||||||
pguardC "All new cosigners are witnessed by their Stake datums" $
|
pcon $
|
||||||
plistEquals # sortedStakeOwners # newSigs
|
PProposalVotes $
|
||||||
|
pupdate
|
||||||
let expectedDatum =
|
# plam
|
||||||
mkRecordConstr
|
( \votes -> unTermCont $ do
|
||||||
PProposalDatum
|
PDiscrete v <- pmatchC stakeInF.stakedAmount
|
||||||
( #proposalId .= proposalF.proposalId
|
pure $ pcon $ PJust $ votes + (pextract # v)
|
||||||
.& #effects .= proposalF.effects
|
|
||||||
.& #status .= proposalF.status
|
|
||||||
.& #cosigners .= pdata updatedSigs
|
|
||||||
.& #thresholds .= proposalF.thresholds
|
|
||||||
.& #votes .= proposalF.votes
|
|
||||||
.& #timingConfig .= proposalF.timingConfig
|
|
||||||
.& #startingTime .= proposalF.startingTime
|
|
||||||
)
|
)
|
||||||
|
# voteFor
|
||||||
|
# m
|
||||||
|
expectedProposalOut =
|
||||||
|
mkRecordConstr
|
||||||
|
PProposalDatum
|
||||||
|
( #proposalId .= proposalF.proposalId
|
||||||
|
.& #effects .= proposalF.effects
|
||||||
|
.& #status .= proposalF.status
|
||||||
|
.& #cosigners .= proposalF.cosigners
|
||||||
|
.& #thresholds .= proposalF.thresholds
|
||||||
|
.& #votes .= pdata expectedNewVotes
|
||||||
|
.& #timingConfig .= proposalF.timingConfig
|
||||||
|
.& #startingTime .= proposalF.startingTime
|
||||||
|
)
|
||||||
|
|
||||||
pguardC "Signatures are correctly added to cosignature list" $
|
pguardC "Output proposal should be valid" $ proposalOut #== expectedProposalOut
|
||||||
proposalOut #== expectedDatum
|
|
||||||
|
|
||||||
pure $ pconstant ()
|
-- 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
|
||||||
|
PProposalLock
|
||||||
|
( #vote .= pdata voteFor
|
||||||
|
.& #proposalTag .= proposalF.proposalId
|
||||||
|
)
|
||||||
|
-- Prepend the new lock to existing locks
|
||||||
|
expectedProposalLocks =
|
||||||
|
pcons
|
||||||
|
# pdata newProposalLock
|
||||||
|
# pfromData stakeInF.lockedBy
|
||||||
|
expectedStakeOut =
|
||||||
|
mkRecordConstr
|
||||||
|
PStakeDatum
|
||||||
|
( #stakedAmount .= stakeInF.stakedAmount
|
||||||
|
.& #owner .= stakeInF.owner
|
||||||
|
.& #lockedBy .= pdata expectedProposalLocks
|
||||||
|
)
|
||||||
|
|
||||||
PAdvanceProposal _ -> do
|
pguardC "Output stake should be locked by the proposal" $ expectedStakeOut #== stakeOut
|
||||||
inDraftPeriod <-
|
|
||||||
pletC $
|
|
||||||
isDraftPeriod # proposalF.timingConfig # proposalF.startingTime # currentTime
|
|
||||||
|
|
||||||
pure $
|
pure $ pconstant ()
|
||||||
pif
|
|
||||||
inDraftPeriod
|
|
||||||
( unTermCont $ do
|
|
||||||
pguardC "More cosigns than minimum amount" $
|
|
||||||
punsafeCoerce (pfromData thresholdsF.vote) #< totalStakedAmount
|
|
||||||
|
|
||||||
pguardC "All new cosigners are witnessed by their Stake datums" $
|
----------------------------------------------------------------------
|
||||||
plistEquals # sortedStakeOwners # proposalF.cosigners
|
|
||||||
|
|
||||||
-- 'Draft' -> 'VotingReady'
|
PUnlock r -> withSingleStake $ \stakeInF stakeOut _ -> do
|
||||||
pguardC "Proposal status set to VotingReady" $
|
-- At draft stage, the votes should be empty.
|
||||||
proposalOutStatus #== pconstant VotingReady
|
pguardC "Shouldn't retract votes from a draft proposal" $
|
||||||
|
pnot #$ currentStatus #== pconstant Draft
|
||||||
|
|
||||||
pure $ pconstant ()
|
-- This is the vote option we're retracting from.
|
||||||
)
|
retractFrom <- pletC $ pfield @"resultTag" # r
|
||||||
( unTermCont $ do
|
|
||||||
pguardC "Advance to failed state" $ proposalOutStatus #== pconstant Finished
|
|
||||||
|
|
||||||
pure $ pconstant ()
|
-- Determine if the input stake is actually locked by this proposal.
|
||||||
)
|
stakeUsage <- pletC $ pgetStakeUsage # stakeInF.lockedBy # proposalF.proposalId
|
||||||
|
|
||||||
------------------------------------------------------------------
|
pguardC "Stake input relevant" $
|
||||||
|
pmatch stakeUsage $ \case
|
||||||
|
PDidNothing ->
|
||||||
|
ptraceIfFalse "Stake should be relevant" $
|
||||||
|
pconstant False
|
||||||
|
PCreated ->
|
||||||
|
ptraceIfFalse "Removing creator's locks means status is Finished" $
|
||||||
|
currentStatus #== pconstant Finished
|
||||||
|
PVotedFor rt ->
|
||||||
|
ptraceIfFalse "Result tag should match the one given in the redeemer" $
|
||||||
|
rt #== retractFrom
|
||||||
|
|
||||||
_ -> pure $ pconstant ()
|
-- The count of removing votes is equal to the 'stakeAmount' of input stake.
|
||||||
)
|
retractCount <-
|
||||||
( unTermCont $ do
|
pletC $
|
||||||
pguardC "Can only deal with one stake" $
|
pmatch stakeInF.stakedAmount $ \(PDiscrete v) -> pextract # v
|
||||||
stakeInputNum #== 1
|
|
||||||
|
|
||||||
let stakeInputHash = pfromData $ phead # stakeInputDatumHashes
|
-- The votes can only change when the proposal still allows voting.
|
||||||
stakeOutputHash = pfromData $ phead # stakeOutputDatumHashes
|
let shouldUpdateVotes =
|
||||||
|
currentStatus #== pconstant VotingReady
|
||||||
|
#&& pnot # (pcon PCreated #== stakeUsage)
|
||||||
|
|
||||||
stakeIn :: Term _ PStakeDatum <-
|
pguardC "Proposal output correct" $
|
||||||
pletC $
|
pif
|
||||||
pfromData $
|
shouldUpdateVotes
|
||||||
pfromJust #$ ptryFindDatum # stakeInputHash # txInfoF.datums
|
( let -- Remove votes and leave other parts of the proposal as it.
|
||||||
stakeInF <- pletFieldsC @'["stakedAmount", "lockedBy", "owner"] stakeIn
|
expectedVotes = pretractVotes # retractFrom # retractCount # proposalF.votes
|
||||||
|
|
||||||
stakeOut :: Term _ PStakeDatum <-
|
|
||||||
pletC $
|
|
||||||
pfromData $
|
|
||||||
pfromJust #$ ptryFindDatum # stakeOutputHash # txInfoF.datums
|
|
||||||
|
|
||||||
redeemer <- pmatchC proposalRedeemer
|
|
||||||
|
|
||||||
case redeemer of
|
|
||||||
PVote r -> do
|
|
||||||
pguardC "Input proposal must be in VotingReady state" $
|
|
||||||
currentStatus #== pconstant VotingReady
|
|
||||||
|
|
||||||
pguardC "Proposal time should be wthin the voting period" $
|
|
||||||
isVotingPeriod # proposalF.timingConfig
|
|
||||||
# proposalF.startingTime
|
|
||||||
# currentTime
|
|
||||||
|
|
||||||
-- Ensure the transaction is voting to a valid 'ResultTag'(outcome).
|
|
||||||
PProposalVotes voteMap <- pmatchC proposalF.votes
|
|
||||||
voteFor <- pletC $ pfromData $ pfield @"resultTag" # r
|
|
||||||
|
|
||||||
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 #$ pany
|
|
||||||
# plam
|
|
||||||
( \((pfield @"proposalTag" #) . pfromData -> pid) ->
|
|
||||||
pid #== proposalF.proposalId
|
|
||||||
)
|
|
||||||
# pfromData 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 = pmatch (pfromData proposalF.votes) $ \(PProposalVotes m) ->
|
|
||||||
pcon $
|
|
||||||
PProposalVotes $
|
|
||||||
pupdate
|
|
||||||
# plam
|
|
||||||
( \votes -> unTermCont $ do
|
|
||||||
PDiscrete v <- pmatchC stakeInF.stakedAmount
|
|
||||||
pure $ pcon $ PJust $ votes + (pextract # v)
|
|
||||||
)
|
|
||||||
# voteFor
|
|
||||||
# m
|
|
||||||
expectedProposalOut =
|
expectedProposalOut =
|
||||||
mkRecordConstr
|
mkRecordConstr
|
||||||
PProposalDatum
|
PProposalDatum
|
||||||
|
|
@ -505,122 +580,60 @@ proposalValidator proposal =
|
||||||
.& #status .= proposalF.status
|
.& #status .= proposalF.status
|
||||||
.& #cosigners .= proposalF.cosigners
|
.& #cosigners .= proposalF.cosigners
|
||||||
.& #thresholds .= proposalF.thresholds
|
.& #thresholds .= proposalF.thresholds
|
||||||
.& #votes .= pdata expectedNewVotes
|
.& #votes .= pdata expectedVotes
|
||||||
.& #timingConfig .= proposalF.timingConfig
|
.& #timingConfig .= proposalF.timingConfig
|
||||||
.& #startingTime .= proposalF.startingTime
|
.& #startingTime .= proposalF.startingTime
|
||||||
)
|
)
|
||||||
|
in ptraceIfFalse "Update votes" $
|
||||||
|
expectedProposalOut #== proposalOut
|
||||||
|
)
|
||||||
|
-- No change to the proposal is allowed.
|
||||||
|
$ ptraceIfFalse "Proposal unchanged" proposalUnchanged
|
||||||
|
|
||||||
pguardC "Output proposal should be valid" $ proposalOut #== expectedProposalOut
|
-- At last, we ensure that all locks belong to this proposal will be removed.
|
||||||
|
stakeOutputLocks <- pletC $ pfield @"lockedBy" # stakeOut
|
||||||
|
|
||||||
-- We validate the output stake datum here as well: We need the vote option
|
let templateStakeOut =
|
||||||
-- to create a valid 'ProposalLock', however the vote option is encoded
|
mkRecordConstr
|
||||||
-- in the proposal redeemer, which is invisible for the stake validator.
|
PStakeDatum
|
||||||
|
( #stakedAmount .= stakeInF.stakedAmount
|
||||||
|
.& #owner .= stakeInF.owner
|
||||||
|
.& #lockedBy .= stakeOutputLocks
|
||||||
|
)
|
||||||
|
|
||||||
let newProposalLock =
|
pguardC "Only locks updated in the output stake" $
|
||||||
mkRecordConstr
|
templateStakeOut #== stakeOut
|
||||||
PProposalLock
|
|
||||||
( #vote .= pdata voteFor
|
|
||||||
.& #proposalTag .= proposalF.proposalId
|
|
||||||
)
|
|
||||||
-- Prepend the new lock to existing locks
|
|
||||||
expectedProposalLocks =
|
|
||||||
pcons
|
|
||||||
# pdata newProposalLock
|
|
||||||
# pfromData stakeInF.lockedBy
|
|
||||||
expectedStakeOut =
|
|
||||||
mkRecordConstr
|
|
||||||
PStakeDatum
|
|
||||||
( #stakedAmount .= stakeInF.stakedAmount
|
|
||||||
.& #owner .= stakeInF.owner
|
|
||||||
.& #lockedBy .= pdata expectedProposalLocks
|
|
||||||
)
|
|
||||||
|
|
||||||
pguardC "Output stake should be locked by the proposal" $ expectedStakeOut #== stakeOut
|
pguardC "All relevant locks removed from the stake" $
|
||||||
|
pgetStakeUsage # pfromData stakeOutputLocks
|
||||||
|
# proposalF.proposalId #== pcon PDidNothing
|
||||||
|
|
||||||
pure $ pconstant ()
|
pure $ pconstant ()
|
||||||
|
|
||||||
------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
PUnlock r -> do
|
|
||||||
-- At draft stage, the votes should be empty.
|
|
||||||
pguardC "Shouldn't retract votes from a draft proposal" $
|
|
||||||
pnot #$ currentStatus #== pconstant Draft
|
|
||||||
|
|
||||||
-- This is the vote option we're retracting from.
|
PAdvanceProposal _ ->
|
||||||
retractFrom <- pletC $ pfield @"resultTag" # r
|
let fromDraft = withMultipleStakes $ \totalStakedAmount sortedStakeOwners ->
|
||||||
|
pmatchC (isDraftPeriod # proposalF.timingConfig # proposalF.startingTime # currentTime) >>= \case
|
||||||
|
PTrue -> do
|
||||||
|
pguardC "More cosigns than minimum amount" $
|
||||||
|
punsafeCoerce (pfromData thresholdsF.vote) #< totalStakedAmount
|
||||||
|
|
||||||
-- Determine if the input stake is actually locked by this proposal.
|
pguardC "All new cosigners are witnessed by their Stake datums" $
|
||||||
stakeUsage <- pletC $ pgetStakeUsage # stakeInF.lockedBy # proposalF.proposalId
|
plistEquals # sortedStakeOwners # proposalF.cosigners
|
||||||
|
|
||||||
pguardC "Stake input relevant" $
|
-- 'Draft' -> 'VotingReady'
|
||||||
pmatch stakeUsage $ \case
|
pguardC "Proposal status set to VotingReady" $
|
||||||
PDidNothing ->
|
proposalOutStatus #== pconstant VotingReady
|
||||||
ptraceIfFalse "Stake should be relevant" $
|
|
||||||
pconstant False
|
|
||||||
PCreated ->
|
|
||||||
ptraceIfFalse "Removing creator's locks means status is Finished" $
|
|
||||||
currentStatus #== pconstant Finished
|
|
||||||
PVotedFor rt ->
|
|
||||||
ptraceIfFalse "Result tag should match the one given in the redeemer" $
|
|
||||||
rt #== retractFrom
|
|
||||||
|
|
||||||
-- The count of removing votes is equal to the 'stakeAmount' of input stake.
|
pure $ pconstant ()
|
||||||
retractCount <-
|
PFalse -> do
|
||||||
pletC $
|
pguardC "Advance to failed state" $ proposalOutStatus #== pconstant Finished
|
||||||
pmatch stakeInF.stakedAmount $ \(PDiscrete v) -> pextract # v
|
|
||||||
|
|
||||||
-- The votes can only change when the proposal still allows voting.
|
pure $ pconstant ()
|
||||||
let shouldUpdateVotes =
|
|
||||||
currentStatus #== pconstant VotingReady
|
|
||||||
#&& pnot # (pcon PCreated #== stakeUsage)
|
|
||||||
|
|
||||||
pguardC "Proposal output correct" $
|
fromOther = withSingleStake $ \_ _ stakeUnchanged -> do
|
||||||
pif
|
pguardC "Stake should not change" stakeUnchanged
|
||||||
shouldUpdateVotes
|
|
||||||
( let -- Remove votes and leave other parts of the proposal as it.
|
|
||||||
expectedVotes = pretractVotes # retractFrom # retractCount # proposalF.votes
|
|
||||||
|
|
||||||
expectedProposalOut =
|
|
||||||
mkRecordConstr
|
|
||||||
PProposalDatum
|
|
||||||
( #proposalId .= proposalF.proposalId
|
|
||||||
.& #effects .= proposalF.effects
|
|
||||||
.& #status .= proposalF.status
|
|
||||||
.& #cosigners .= proposalF.cosigners
|
|
||||||
.& #thresholds .= proposalF.thresholds
|
|
||||||
.& #votes .= pdata expectedVotes
|
|
||||||
.& #timingConfig .= proposalF.timingConfig
|
|
||||||
.& #startingTime .= proposalF.startingTime
|
|
||||||
)
|
|
||||||
in ptraceIfFalse "Update votes" $
|
|
||||||
expectedProposalOut #== proposalOut
|
|
||||||
)
|
|
||||||
-- No change to the proposal is allowed.
|
|
||||||
$ ptraceIfFalse "Proposal unchanged" proposalUnchanged
|
|
||||||
|
|
||||||
-- At last, we ensure that all locks belong to this proposal will be removed.
|
|
||||||
stakeOutputLocks <- pletC $ pfield @"lockedBy" # stakeOut
|
|
||||||
|
|
||||||
let templateStakeOut =
|
|
||||||
mkRecordConstr
|
|
||||||
PStakeDatum
|
|
||||||
( #stakedAmount .= stakeInF.stakedAmount
|
|
||||||
.& #owner .= stakeInF.owner
|
|
||||||
.& #lockedBy .= stakeOutputLocks
|
|
||||||
)
|
|
||||||
|
|
||||||
pguardC "Only locks updated in the output stake" $
|
|
||||||
templateStakeOut #== stakeOut
|
|
||||||
|
|
||||||
pguardC "All relevant locks removed from the stake" $
|
|
||||||
pgetStakeUsage # pfromData stakeOutputLocks
|
|
||||||
# proposalF.proposalId #== pcon PDidNothing
|
|
||||||
|
|
||||||
pure $ pconstant ()
|
|
||||||
|
|
||||||
------------------------------------------------------------------
|
|
||||||
PAdvanceProposal _ -> do
|
|
||||||
pguardC "Stake should not change" $
|
|
||||||
stakeInputHash #== stakeOutputHash
|
|
||||||
|
|
||||||
pguardC
|
pguardC
|
||||||
"Only status changes in the output proposal"
|
"Only status changes in the output proposal"
|
||||||
|
|
@ -655,6 +668,7 @@ proposalValidator proposal =
|
||||||
|
|
||||||
-- TODO: Should check that the GST is not moved
|
-- TODO: Should check that the GST is not moved
|
||||||
-- if the proposal is in 'Locked' state.
|
-- if the proposal is in 'Locked' state.
|
||||||
|
|
||||||
pure $ pconstant ()
|
pure $ pconstant ()
|
||||||
|
|
||||||
toNextState = pmatchEnum proposalStatus $ \case
|
toNextState = pmatchEnum proposalStatus $ \case
|
||||||
|
|
@ -685,5 +699,4 @@ proposalValidator proposal =
|
||||||
toNextState
|
toNextState
|
||||||
-- Too late: failed proposal, status set to 'Finished'.
|
-- Too late: failed proposal, status set to 'Finished'.
|
||||||
toFailedState
|
toFailedState
|
||||||
_ -> pure $ pconstant ()
|
in pif (currentStatus #== pconstant Draft) fromDraft fromOther
|
||||||
)
|
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import Agora.Utils (
|
||||||
mustFindDatum',
|
mustFindDatum',
|
||||||
pvalidatorHashToTokenName,
|
pvalidatorHashToTokenName,
|
||||||
)
|
)
|
||||||
|
import Data.Function (on)
|
||||||
import Data.Tagged (Tagged (..), untag)
|
import Data.Tagged (Tagged (..), untag)
|
||||||
import Plutarch.Api.V1 (
|
import Plutarch.Api.V1 (
|
||||||
AmountGuarantees (Positive),
|
AmountGuarantees (Positive),
|
||||||
|
|
@ -303,10 +304,10 @@ stakeValidator stake =
|
||||||
# pfromData txInfoF.outputs
|
# pfromData txInfoF.outputs
|
||||||
|
|
||||||
let witnessStake = unTermCont $ do
|
let witnessStake = unTermCont $ do
|
||||||
pguardC "Either owner signs the transaction or propsoal token moved" $
|
pguardC "Either owner signs the transaction or proposal token moved" $
|
||||||
ownerSignsTransaction #|| proposalTokenMoved
|
ownerSignsTransaction #|| proposalTokenMoved
|
||||||
|
|
||||||
-- FIXME: refactor this with reference input, once it's supported by plutarch.
|
-- FIXME: remove this once we have reference input.
|
||||||
--
|
--
|
||||||
-- Our goal here is to allow multiple input stakes, and also ensure that every the input stakes has a
|
-- Our goal here is to allow multiple input stakes, and also ensure that every the input stakes has a
|
||||||
-- corresponding output stake, which carries the same value and the same datum as the input stake.
|
-- corresponding output stake, which carries the same value and the same datum as the input stake.
|
||||||
|
|
@ -335,15 +336,7 @@ stakeValidator stake =
|
||||||
# pfromData txInfoF.inputs
|
# pfromData txInfoF.inputs
|
||||||
|
|
||||||
sortTxOuts :: Term _ (PBuiltinList (PAsData PTxOut) :--> PBuiltinList (PAsData PTxOut))
|
sortTxOuts :: Term _ (PBuiltinList (PAsData PTxOut) :--> PBuiltinList (PAsData PTxOut))
|
||||||
sortTxOuts =
|
sortTxOuts = phoistAcyclic $ plam (pmsortBy # plam ((#<) `on` (getDatumHash #)) #)
|
||||||
plam
|
|
||||||
( pmsortBy
|
|
||||||
# plam
|
|
||||||
( \((getDatumHash #) -> dhX)
|
|
||||||
((getDatumHash #) -> dhY) -> dhX #< dhY
|
|
||||||
)
|
|
||||||
#
|
|
||||||
)
|
|
||||||
where
|
where
|
||||||
getDatumHash :: Term _ (PAsData PTxOut :--> PDatumHash)
|
getDatumHash :: Term _ (PAsData PTxOut :--> PDatumHash)
|
||||||
getDatumHash = phoistAcyclic $ plam ((pfromDJust #) . pfromData . (pfield @"datumHash" #))
|
getDatumHash = phoistAcyclic $ plam ((pfromDJust #) . pfromData . (pfield @"datumHash" #))
|
||||||
|
|
@ -464,7 +457,7 @@ stakeValidator stake =
|
||||||
|
|
||||||
newStakedAmount <- pletC $ oldStakedAmount + delta
|
newStakedAmount <- pletC $ oldStakedAmount + delta
|
||||||
|
|
||||||
pguardC "New staked amount shoudl be greater than or equal to 0" $
|
pguardC "New staked amount should be greater than or equal to 0" $
|
||||||
zero #<= newStakedAmount
|
zero #<= newStakedAmount
|
||||||
|
|
||||||
let expectedDatum =
|
let expectedDatum =
|
||||||
|
|
|
||||||
108
bench.csv
108
bench.csv
|
|
@ -5,60 +5,60 @@ Agora/Effects/Treasury Withdrawal Effect/effect/Mixed Assets,456007605,1104500,3
|
||||||
Agora/Effects/Governor Mutation Effect/validator/valid new governor datum/governor validator should pass,87839169,243032,8561
|
Agora/Effects/Governor Mutation Effect/validator/valid new governor datum/governor validator should pass,87839169,243032,8561
|
||||||
Agora/Effects/Governor Mutation Effect/validator/valid new governor datum/effect validator should pass,106082031,292993,3609
|
Agora/Effects/Governor Mutation Effect/validator/valid new governor datum/effect validator should pass,106082031,292993,3609
|
||||||
Agora/Stake/policy/stakeCreation,50939580,148729,2387
|
Agora/Stake/policy/stakeCreation,50939580,148729,2387
|
||||||
Agora/Stake/validator/stakeDepositWithdraw deposit,180222751,492217,5003
|
Agora/Stake/validator/stakeDepositWithdraw deposit,150745141,416137,4995
|
||||||
Agora/Stake/validator/stakeDepositWithdraw withdraw,180222751,492217,4991
|
Agora/Stake/validator/stakeDepositWithdraw withdraw,150745141,416137,4983
|
||||||
Agora/Proposal/policy/proposalCreation,23140177,69194,1515
|
Agora/Proposal/policy/proposalCreation,23140177,69194,1515
|
||||||
Agora/Proposal/validator/cosignature/legal/with 1 cosigners/propsoal,237484909,663370,8471
|
Agora/Proposal/validator/cosignature/legal/with 1 cosigners/propsoal,235408912,657765,8097
|
||||||
Agora/Proposal/validator/cosignature/legal/with 1 cosigners/stake,123296365,319226,5470
|
Agora/Proposal/validator/cosignature/legal/with 1 cosigners/stake,125665131,316762,5462
|
||||||
Agora/Proposal/validator/cosignature/legal/with 5 cosigners/propsoal,675336848,1882805,11101
|
Agora/Proposal/validator/cosignature/legal/with 5 cosigners/propsoal,680441047,1897008,10727
|
||||||
Agora/Proposal/validator/cosignature/legal/with 5 cosigners/stake,554091553,1461634,7980
|
Agora/Proposal/validator/cosignature/legal/with 5 cosigners/stake,576106975,1490610,7972
|
||||||
Agora/Proposal/validator/cosignature/legal/with 10 cosigners/propsoal,1336993992,3667352,14389
|
Agora/Proposal/validator/cosignature/legal/with 10 cosigners/propsoal,1351073436,3706315,14015
|
||||||
Agora/Proposal/validator/cosignature/legal/with 10 cosigners/stake,1102063894,2914419,11117
|
Agora/Proposal/validator/cosignature/legal/with 10 cosigners/stake,1148637636,2982695,11109
|
||||||
Agora/Proposal/validator/cosignature/illegal/duplicate cosigners/stake,123296365,319226,5470
|
Agora/Proposal/validator/cosignature/illegal/duplicate cosigners/stake,125665131,316762,5462
|
||||||
Agora/Proposal/validator/cosignature/illegal/proposal status not Draft/with 1 cosigners/status: VotingReady/stake,123296365,319226,5470
|
Agora/Proposal/validator/cosignature/illegal/proposal status not Draft/with 1 cosigners/status: VotingReady/stake,125665131,316762,5462
|
||||||
Agora/Proposal/validator/cosignature/illegal/proposal status not Draft/with 1 cosigners/status: Locked/stake,123296365,319226,5470
|
Agora/Proposal/validator/cosignature/illegal/proposal status not Draft/with 1 cosigners/status: Locked/stake,125665131,316762,5462
|
||||||
Agora/Proposal/validator/cosignature/illegal/proposal status not Draft/with 1 cosigners/status: Finished/stake,123296365,319226,5470
|
Agora/Proposal/validator/cosignature/illegal/proposal status not Draft/with 1 cosigners/status: Finished/stake,125665131,316762,5462
|
||||||
Agora/Proposal/validator/cosignature/illegal/proposal status not Draft/with 5 cosigners/status: VotingReady/stake,554091553,1461634,7980
|
Agora/Proposal/validator/cosignature/illegal/proposal status not Draft/with 5 cosigners/status: VotingReady/stake,576106975,1490610,7972
|
||||||
Agora/Proposal/validator/cosignature/illegal/proposal status not Draft/with 5 cosigners/status: Locked/stake,554091553,1461634,7980
|
Agora/Proposal/validator/cosignature/illegal/proposal status not Draft/with 5 cosigners/status: Locked/stake,576106975,1490610,7972
|
||||||
Agora/Proposal/validator/cosignature/illegal/proposal status not Draft/with 5 cosigners/status: Finished/stake,554091553,1461634,7980
|
Agora/Proposal/validator/cosignature/illegal/proposal status not Draft/with 5 cosigners/status: Finished/stake,576106975,1490610,7972
|
||||||
Agora/Proposal/validator/cosignature/illegal/proposal status not Draft/with 10 cosigners/status: VotingReady/stake,1102063894,2914419,11117
|
Agora/Proposal/validator/cosignature/illegal/proposal status not Draft/with 10 cosigners/status: VotingReady/stake,1148637636,2982695,11109
|
||||||
Agora/Proposal/validator/cosignature/illegal/proposal status not Draft/with 10 cosigners/status: Locked/stake,1102063894,2914419,11117
|
Agora/Proposal/validator/cosignature/illegal/proposal status not Draft/with 10 cosigners/status: Locked/stake,1148637636,2982695,11109
|
||||||
Agora/Proposal/validator/cosignature/illegal/proposal status not Draft/with 10 cosigners/status: Finished/stake,1102063894,2914419,11117
|
Agora/Proposal/validator/cosignature/illegal/proposal status not Draft/with 10 cosigners/status: Finished/stake,1148637636,2982695,11109
|
||||||
Agora/Proposal/validator/voting/legal/propsoal,247594094,689025,8443
|
Agora/Proposal/validator/voting/legal/propsoal,246896882,688919,8069
|
||||||
Agora/Proposal/validator/voting/legal/stake,141390725,374830,5489
|
Agora/Proposal/validator/voting/legal/stake,141234659,368136,5481
|
||||||
Agora/Proposal/validator/advancing/from draft/with 1 cosigner(s)/legal/to next state/propsoal,222990625,630700,8426
|
Agora/Proposal/validator/advancing/from draft/with 1 cosigner(s)/legal/to next state/propsoal,222376736,631090,8052
|
||||||
Agora/Proposal/validator/advancing/from draft/with 1 cosigner(s)/legal/to next state/stake,123296365,319226,5467
|
Agora/Proposal/validator/advancing/from draft/with 1 cosigner(s)/legal/to next state/stake,125665131,316762,5459
|
||||||
Agora/Proposal/validator/advancing/from draft/with 1 cosigner(s)/legal/to failed state/propsoal,217935933,619979,8428
|
Agora/Proposal/validator/advancing/from draft/with 1 cosigner(s)/legal/to failed state/propsoal,217322044,620369,8054
|
||||||
Agora/Proposal/validator/advancing/from draft/with 1 cosigner(s)/legal/to failed state/stake,123296365,319226,5469
|
Agora/Proposal/validator/advancing/from draft/with 1 cosigner(s)/legal/to failed state/stake,125665131,316762,5461
|
||||||
Agora/Proposal/validator/advancing/from draft/with 1 cosigner(s)/illegal/insufficient cosigns/stake,117222929,305504,5397
|
Agora/Proposal/validator/advancing/from draft/with 1 cosigner(s)/illegal/insufficient cosigns/stake,118020743,304972,5389
|
||||||
Agora/Proposal/validator/advancing/from draft/with 5 cosigner(s)/legal/to next state/propsoal,600833052,1725797,11249
|
Agora/Proposal/validator/advancing/from draft/with 5 cosigner(s)/legal/to next state/propsoal,614587307,1766683,10875
|
||||||
Agora/Proposal/validator/advancing/from draft/with 5 cosigner(s)/legal/to next state/stake,526604275,1381680,8170
|
Agora/Proposal/validator/advancing/from draft/with 5 cosigner(s)/legal/to next state/stake,548619697,1410656,8162
|
||||||
Agora/Proposal/validator/advancing/from draft/with 5 cosigner(s)/legal/to failed state/propsoal,240305281,682043,8789
|
Agora/Proposal/validator/advancing/from draft/with 5 cosigner(s)/legal/to failed state/propsoal,239691392,682433,8415
|
||||||
Agora/Proposal/validator/advancing/from draft/with 5 cosigner(s)/legal/to failed state/stake,123296365,319226,5710
|
Agora/Proposal/validator/advancing/from draft/with 5 cosigner(s)/legal/to failed state/stake,125665131,316762,5702
|
||||||
Agora/Proposal/validator/advancing/from draft/with 5 cosigner(s)/illegal/insufficient cosigns/stake,445454241,1167344,7819
|
Agora/Proposal/validator/advancing/from draft/with 5 cosigner(s)/illegal/insufficient cosigns/stake,446252055,1166812,7811
|
||||||
Agora/Proposal/validator/advancing/from draft/with 10 cosigner(s)/legal/to next state/propsoal,1164574757,3363392,14778
|
Agora/Proposal/validator/advancing/from draft/with 10 cosigner(s)/legal/to next state/propsoal,1196289192,3454898,14404
|
||||||
Agora/Proposal/validator/advancing/from draft/with 10 cosigner(s)/legal/to next state/stake,1154814568,3068129,11548
|
Agora/Proposal/validator/advancing/from draft/with 10 cosigner(s)/legal/to next state/stake,1201388310,3136405,11540
|
||||||
Agora/Proposal/validator/advancing/from draft/with 10 cosigner(s)/legal/to failed state/propsoal,268266966,759623,9242
|
Agora/Proposal/validator/advancing/from draft/with 10 cosigner(s)/legal/to failed state/propsoal,267653077,760013,8868
|
||||||
Agora/Proposal/validator/advancing/from draft/with 10 cosigner(s)/legal/to failed state/stake,123296365,319226,6012
|
Agora/Proposal/validator/advancing/from draft/with 10 cosigner(s)/legal/to failed state/stake,125665131,316762,6004
|
||||||
Agora/Proposal/validator/advancing/from draft/with 10 cosigner(s)/illegal/insufficient cosigns/stake,1024215053,2732615,10845
|
Agora/Proposal/validator/advancing/from draft/with 10 cosigner(s)/illegal/insufficient cosigns/stake,1025012867,2732083,10837
|
||||||
Agora/Proposal/validator/advancing/legal/advance to next state/from: VotingReady/propsoal,251396469,709467,8435
|
Agora/Proposal/validator/advancing/legal/advance to next state/from: VotingReady/propsoal,250229153,709227,8061
|
||||||
Agora/Proposal/validator/advancing/legal/advance to next state/from: VotingReady/stake,123296365,319226,5474
|
Agora/Proposal/validator/advancing/legal/advance to next state/from: VotingReady/stake,125665131,316762,5466
|
||||||
Agora/Proposal/validator/advancing/legal/advance to next state/from: Locked/propsoal,240157360,676636,8435
|
Agora/Proposal/validator/advancing/legal/advance to next state/from: Locked/propsoal,238990044,676396,8061
|
||||||
Agora/Proposal/validator/advancing/legal/advance to next state/from: Locked/stake,123296365,319226,5474
|
Agora/Proposal/validator/advancing/legal/advance to next state/from: Locked/stake,125665131,316762,5466
|
||||||
Agora/Proposal/validator/advancing/legal/advance to failed state/from: VotingReady/propsoal,237329915,670626,8429
|
Agora/Proposal/validator/advancing/legal/advance to failed state/from: VotingReady/propsoal,236162599,670386,8055
|
||||||
Agora/Proposal/validator/advancing/legal/advance to failed state/from: VotingReady/stake,123296365,319226,5470
|
Agora/Proposal/validator/advancing/legal/advance to failed state/from: VotingReady/stake,125665131,316762,5462
|
||||||
Agora/Proposal/validator/advancing/legal/advance to failed state/from: Locked/propsoal,238460893,673030,8429
|
Agora/Proposal/validator/advancing/legal/advance to failed state/from: Locked/propsoal,237293577,672790,8055
|
||||||
Agora/Proposal/validator/advancing/legal/advance to failed state/from: Locked/stake,123296365,319226,5470
|
Agora/Proposal/validator/advancing/legal/advance to failed state/from: Locked/stake,125665131,316762,5462
|
||||||
Agora/Proposal/validator/advancing/illegal/insufficient votes/stake,123296365,319226,5470
|
Agora/Proposal/validator/advancing/illegal/insufficient votes/stake,125665131,316762,5462
|
||||||
Agora/Proposal/validator/advancing/illegal/initial state is Finished/stake,123296365,319226,5462
|
Agora/Proposal/validator/advancing/illegal/initial state is Finished/stake,125665131,316762,5454
|
||||||
"Agora/Proposal/validator/unlocking/legal/1 proposals, voter, unlock stake + retract votes, VotingReady",245987595,688711,8403
|
"Agora/Proposal/validator/unlocking/legal/1 proposals, voter, unlock stake + retract votes, VotingReady",245855872,689807,8029
|
||||||
"Agora/Proposal/validator/unlocking/legal/1 proposals, creator, unlock stake, Finished",215263333,612711,8405
|
"Agora/Proposal/validator/unlocking/legal/1 proposals, creator, unlock stake, Finished",215131610,613807,8031
|
||||||
"Agora/Proposal/validator/unlocking/legal/voter unlocks stake after voting/1 proposals, voter, unlock stake, Finished",212560614,604622,8407
|
"Agora/Proposal/validator/unlocking/legal/voter unlocks stake after voting/1 proposals, voter, unlock stake, Finished",212428891,605718,8033
|
||||||
"Agora/Proposal/validator/unlocking/legal/voter unlocks stake after voting/1 proposals, voter, unlock stake, Locked",212560614,604622,8407
|
"Agora/Proposal/validator/unlocking/legal/voter unlocks stake after voting/1 proposals, voter, unlock stake, Locked",212428891,605718,8033
|
||||||
"Agora/Proposal/validator/unlocking/legal/42 proposals, voter, unlock stake + retract votes, VotingReady",1775652167,5199490,29511
|
"Agora/Proposal/validator/unlocking/legal/42 proposals, voter, unlock stake + retract votes, VotingReady",1775520444,5200586,29137
|
||||||
"Agora/Proposal/validator/unlocking/legal/42 proposals, creator, unlock stake, Finished",1448293766,4317963,29695
|
"Agora/Proposal/validator/unlocking/legal/42 proposals, creator, unlock stake, Finished",1448162043,4319059,29321
|
||||||
"Agora/Proposal/validator/unlocking/legal/voter unlocks stake after voting/42 proposals, voter, unlock stake, Finished",1340653392,3978430,29679
|
"Agora/Proposal/validator/unlocking/legal/voter unlocks stake after voting/42 proposals, voter, unlock stake, Finished",1340521669,3979526,29305
|
||||||
"Agora/Proposal/validator/unlocking/legal/voter unlocks stake after voting/42 proposals, voter, unlock stake, Locked",1340653392,3978430,29679
|
"Agora/Proposal/validator/unlocking/legal/voter unlocks stake after voting/42 proposals, voter, unlock stake, Locked",1340521669,3979526,29305
|
||||||
Agora/AuthorityToken/singleAuthorityTokenBurned/Correct simple,21017788,55883,806
|
Agora/AuthorityToken/singleAuthorityTokenBurned/Correct simple,21017788,55883,806
|
||||||
Agora/AuthorityToken/singleAuthorityTokenBurned/Correct many inputs,33204186,88241,900
|
Agora/AuthorityToken/singleAuthorityTokenBurned/Correct many inputs,33204186,88241,900
|
||||||
Agora/Treasury/Validator/Positive/Allows for effect changes,31556709,81546,1452
|
Agora/Treasury/Validator/Positive/Allows for effect changes,31556709,81546,1452
|
||||||
|
|
@ -66,5 +66,5 @@ Agora/AuthorityToken/singleAuthorityTokenBurned/Correct simple,21017788,55883,80
|
||||||
Agora/AuthorityToken/singleAuthorityTokenBurned/Correct many inputs,33204186,88241,900
|
Agora/AuthorityToken/singleAuthorityTokenBurned/Correct many inputs,33204186,88241,900
|
||||||
Agora/Governor/policy/GST minting,51007235,144191,2034
|
Agora/Governor/policy/GST minting,51007235,144191,2034
|
||||||
Agora/Governor/validator/proposal creation,309689999,834675,9064
|
Agora/Governor/validator/proposal creation,309689999,834675,9064
|
||||||
Agora/Governor/validator/GATs minting,421016677,1141838,9187
|
Agora/Governor/validator/GATs minting,418560845,1137908,9187
|
||||||
Agora/Governor/validator/mutate governor state,88986020,248491,8662
|
Agora/Governor/validator/mutate governor state,88986020,248491,8662
|
||||||
|
|
|
||||||
|
Loading…
Add table
Add a link
Reference in a new issue