add samples and tests for unlocking stakes
This commit is contained in:
parent
a1c5d0e339
commit
034e55c34f
3 changed files with 541 additions and 5 deletions
|
|
@ -19,6 +19,14 @@ module Sample.Proposal (
|
||||||
advanceFinishedPropsoal,
|
advanceFinishedPropsoal,
|
||||||
advanceProposalInsufficientVotes,
|
advanceProposalInsufficientVotes,
|
||||||
advancePropsoalWithInvalidOutputStake,
|
advancePropsoalWithInvalidOutputStake,
|
||||||
|
voterUnlockStakeAndRetractVotesWhile,
|
||||||
|
voterUnlockStakeWhile,
|
||||||
|
creatorRetractVotesWhile,
|
||||||
|
creatorUnlockStakeWhile,
|
||||||
|
unlockStakeAndRetractVotesUsingIrrelevantStakeWhile,
|
||||||
|
unlockStakeUsingIrrelevantStakeWhile,
|
||||||
|
unlockStakeProposalId,
|
||||||
|
unlockStake,
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Agora.Governor (GovernorDatum (..))
|
import Agora.Governor (GovernorDatum (..))
|
||||||
|
|
@ -78,17 +86,14 @@ import PlutusLedgerApi.V1.Value qualified as Value (
|
||||||
assetClassValue,
|
assetClassValue,
|
||||||
singleton,
|
singleton,
|
||||||
)
|
)
|
||||||
import PlutusTx.AssocMap qualified as AssocMap (
|
import PlutusTx.AssocMap qualified as AssocMap
|
||||||
Map,
|
|
||||||
empty,
|
|
||||||
fromList,
|
|
||||||
)
|
|
||||||
import Sample.Shared (
|
import Sample.Shared (
|
||||||
govValidatorHash,
|
govValidatorHash,
|
||||||
minAda,
|
minAda,
|
||||||
proposal,
|
proposal,
|
||||||
proposalPolicySymbol,
|
proposalPolicySymbol,
|
||||||
proposalStartingTimeFromTimeRange,
|
proposalStartingTimeFromTimeRange,
|
||||||
|
proposalValidatorAddress,
|
||||||
proposalValidatorHash,
|
proposalValidatorHash,
|
||||||
signer,
|
signer,
|
||||||
signer2,
|
signer2,
|
||||||
|
|
@ -808,3 +813,280 @@ advancePropsoalWithInvalidOutputStake =
|
||||||
<> templateTxInfo.txInfoData
|
<> templateTxInfo.txInfoData
|
||||||
, txInfoSignatories = [stakeOwner]
|
, txInfoSignatories = [stakeOwner]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- | Create empty effects for every result tag given the votes.
|
||||||
|
emptyEffectFor ::
|
||||||
|
ProposalVotes ->
|
||||||
|
AssocMap.Map ResultTag (AssocMap.Map ValidatorHash DatumHash)
|
||||||
|
emptyEffectFor (ProposalVotes vs) =
|
||||||
|
AssocMap.fromList $
|
||||||
|
map (,AssocMap.empty) (AssocMap.keys vs)
|
||||||
|
|
||||||
|
-- | The proposal id shared by all the samples relate to unlocking stake.
|
||||||
|
unlockStakeProposalId :: ProposalId
|
||||||
|
unlockStakeProposalId = ProposalId 0
|
||||||
|
|
||||||
|
-- | A 'ProposalVotes' that has only two options, serves as a template for unlokcing stake samples.
|
||||||
|
unlockStakePropsoalVotesTemplate :: ProposalVotes
|
||||||
|
unlockStakePropsoalVotesTemplate =
|
||||||
|
ProposalVotes $
|
||||||
|
AssocMap.fromList
|
||||||
|
[ (ResultTag 0, 0)
|
||||||
|
, (ResultTag 1, 0)
|
||||||
|
]
|
||||||
|
|
||||||
|
-- | Create a 'TxInfo' that unlocks a stake from a proposal. For internal use only.
|
||||||
|
mkUnlockStakeTxInfo ::
|
||||||
|
-- | The current state of the proposal.
|
||||||
|
ProposalStatus ->
|
||||||
|
-- | The votes of the input propsoal
|
||||||
|
ProposalVotes ->
|
||||||
|
-- | The votes of the output proposal.
|
||||||
|
ProposalVotes ->
|
||||||
|
-- | Stake amount.
|
||||||
|
Integer ->
|
||||||
|
-- | Retract from option.
|
||||||
|
[ProposalLock] ->
|
||||||
|
-- | The locks of output stake.
|
||||||
|
[ProposalLock] ->
|
||||||
|
TxInfo
|
||||||
|
mkUnlockStakeTxInfo
|
||||||
|
status
|
||||||
|
votesBefore
|
||||||
|
votesAfter
|
||||||
|
stakedAmount
|
||||||
|
locksBefore
|
||||||
|
locksAfter =
|
||||||
|
let stakeOwner = signer
|
||||||
|
|
||||||
|
stakeInputDatum' :: StakeDatum
|
||||||
|
stakeInputDatum' =
|
||||||
|
StakeDatum
|
||||||
|
{ stakedAmount = Tagged stakedAmount
|
||||||
|
, owner = stakeOwner
|
||||||
|
, lockedBy = locksBefore
|
||||||
|
}
|
||||||
|
|
||||||
|
stakeOutputDatum' :: StakeDatum
|
||||||
|
stakeOutputDatum' =
|
||||||
|
stakeInputDatum'
|
||||||
|
{ lockedBy = locksAfter
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
effects = emptyEffectFor votesBefore
|
||||||
|
|
||||||
|
proposalInputDatum' :: ProposalDatum
|
||||||
|
proposalInputDatum' =
|
||||||
|
ProposalDatum
|
||||||
|
{ proposalId = unlockStakeProposalId
|
||||||
|
, effects = effects
|
||||||
|
, status = status
|
||||||
|
, cosigners = [signer]
|
||||||
|
, thresholds = def
|
||||||
|
, votes = votesBefore
|
||||||
|
, timingConfig = def
|
||||||
|
, startingTime = ProposalStartingTime 0
|
||||||
|
}
|
||||||
|
|
||||||
|
proposalOutputDatum' :: ProposalDatum
|
||||||
|
proposalOutputDatum' =
|
||||||
|
proposalInputDatum'
|
||||||
|
{ votes = votesAfter
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
sst = Value.assetClassValue stakeAssetClass 1
|
||||||
|
|
||||||
|
stakeInputDatum :: Datum
|
||||||
|
stakeInputDatum = Datum $ toBuiltinData stakeInputDatum'
|
||||||
|
stakeInput :: TxOut
|
||||||
|
stakeInput =
|
||||||
|
TxOut
|
||||||
|
{ txOutAddress = stakeAddress
|
||||||
|
, txOutValue =
|
||||||
|
mconcat
|
||||||
|
[ sst
|
||||||
|
, Value.assetClassValue (untag stake.gtClassRef) stakedAmount
|
||||||
|
, minAda
|
||||||
|
]
|
||||||
|
, txOutDatumHash = Just $ toDatumHash stakeInputDatum
|
||||||
|
}
|
||||||
|
|
||||||
|
stakeOutputDatum :: Datum
|
||||||
|
stakeOutputDatum = Datum $ toBuiltinData stakeOutputDatum'
|
||||||
|
stakeOutput :: TxOut
|
||||||
|
stakeOutput =
|
||||||
|
stakeInput
|
||||||
|
{ txOutDatumHash = Just $ toDatumHash stakeOutputDatum
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
pst = Value.singleton proposalPolicySymbol "" 1
|
||||||
|
|
||||||
|
proposalInputDatum :: Datum
|
||||||
|
proposalInputDatum = Datum $ toBuiltinData proposalInputDatum'
|
||||||
|
proposalInput :: TxOut
|
||||||
|
proposalInput =
|
||||||
|
TxOut
|
||||||
|
{ txOutAddress = proposalValidatorAddress
|
||||||
|
, txOutValue = pst
|
||||||
|
, txOutDatumHash = Just $ toDatumHash proposalInputDatum
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
proposalOutputDatum :: Datum
|
||||||
|
proposalOutputDatum = Datum $ toBuiltinData proposalOutputDatum'
|
||||||
|
proposalOutput :: TxOut
|
||||||
|
proposalOutput =
|
||||||
|
proposalInput
|
||||||
|
{ txOutValue = proposalInput.txOutValue <> minAda
|
||||||
|
, txOutDatumHash = Just $ toDatumHash proposalOutputDatum
|
||||||
|
}
|
||||||
|
in TxInfo
|
||||||
|
{ txInfoInputs = [TxInInfo proposalRef proposalInput, TxInInfo stakeRef stakeInput]
|
||||||
|
, txInfoOutputs = [proposalOutput, stakeOutput]
|
||||||
|
, txInfoFee = Value.singleton "" "" 2
|
||||||
|
, txInfoMint = mempty
|
||||||
|
, txInfoDCert = []
|
||||||
|
, txInfoWdrl = []
|
||||||
|
, -- Time doesn't matter int this case.
|
||||||
|
txInfoValidRange = closedBoundedInterval 0 100
|
||||||
|
, txInfoSignatories = [signer]
|
||||||
|
, txInfoData = datumPair <$> [proposalInputDatum, proposalOutputDatum, stakeInputDatum, stakeOutputDatum]
|
||||||
|
, txInfoId = "95ba4015e30aef16a3461ea97a779f814aeea6b8009d99a94add4b8293be737a"
|
||||||
|
}
|
||||||
|
|
||||||
|
-- | How a stake has been used on a particular proposal.
|
||||||
|
data StakeUsage
|
||||||
|
= -- | The stake was spent to vote for a paraticular option.
|
||||||
|
VotedFor ResultTag
|
||||||
|
| -- | The stake was used to created the proposal.
|
||||||
|
Created
|
||||||
|
| -- | The stake has nothing to do with the proposal.
|
||||||
|
DidNothing
|
||||||
|
|
||||||
|
-- | Create a bunch of 'ProposalLock' given the 'StakeUsgae'.
|
||||||
|
mkStakeLocks :: StakeUsage -> [ProposalLock]
|
||||||
|
mkStakeLocks (VotedFor rt) = [ProposalLock rt unlockStakeProposalId]
|
||||||
|
mkStakeLocks Created =
|
||||||
|
map (`ProposalLock` unlockStakeProposalId) $
|
||||||
|
AssocMap.keys $ getProposalVotes unlockStakePropsoalVotesTemplate
|
||||||
|
mkStakeLocks _ = []
|
||||||
|
|
||||||
|
-- | Assemble the votes of the input propsoal based on 'unlockStakePropsoalVotesTemplate'.
|
||||||
|
mkVotesBefore ::
|
||||||
|
StakeUsage ->
|
||||||
|
-- | The staked amount/votes.
|
||||||
|
Integer ->
|
||||||
|
ProposalVotes
|
||||||
|
mkVotesBefore (VotedFor rt) vc =
|
||||||
|
ProposalVotes $
|
||||||
|
updateMap (Just . const vc) rt $
|
||||||
|
getProposalVotes unlockStakePropsoalVotesTemplate
|
||||||
|
mkVotesBefore _ vc = mkVotesBefore (VotedFor $ ResultTag 0) vc
|
||||||
|
|
||||||
|
{- | Create a 'TxInfo' that unlocks the stake from the proposal.
|
||||||
|
The last parameter controls whether votes should be retracted or not.
|
||||||
|
-}
|
||||||
|
unlockStake ::
|
||||||
|
-- | The status of both the input and output propsoals.
|
||||||
|
ProposalStatus ->
|
||||||
|
StakeUsage ->
|
||||||
|
-- | Staked amount/vote count.
|
||||||
|
Integer ->
|
||||||
|
-- | Should we retract votes?
|
||||||
|
Bool ->
|
||||||
|
TxInfo
|
||||||
|
unlockStake ps su staked shouldRetract =
|
||||||
|
let votesBefore = mkVotesBefore su staked
|
||||||
|
votesAfter =
|
||||||
|
if shouldRetract
|
||||||
|
then unlockStakePropsoalVotesTemplate
|
||||||
|
else votesBefore
|
||||||
|
|
||||||
|
locksBefore = mkStakeLocks su
|
||||||
|
locksAfter = []
|
||||||
|
in mkUnlockStakeTxInfo
|
||||||
|
ps
|
||||||
|
votesBefore
|
||||||
|
votesAfter
|
||||||
|
staked
|
||||||
|
locksBefore
|
||||||
|
locksAfter
|
||||||
|
|
||||||
|
{- | Create a 'TxInfo' that unlocks a stake which is used to vote on the proposal.
|
||||||
|
Correct count of votes is also retracted. The 'TxInfo' is valid only if the given
|
||||||
|
proposal status is 'VotingReady'.
|
||||||
|
-}
|
||||||
|
voterUnlockStakeAndRetractVotesWhile :: ProposalStatus -> TxInfo
|
||||||
|
voterUnlockStakeAndRetractVotesWhile ps =
|
||||||
|
unlockStake
|
||||||
|
ps
|
||||||
|
(VotedFor $ ResultTag 0)
|
||||||
|
42
|
||||||
|
True
|
||||||
|
|
||||||
|
{- | Create a 'TxInfo' that unlocks a stake which is used to vote on the proposal
|
||||||
|
without retracting the votes, given the status of the proposal.
|
||||||
|
|
||||||
|
The 'TxInfo' is valid only if the status of the propsoal is either 'Locked'
|
||||||
|
or 'Finished'.
|
||||||
|
-}
|
||||||
|
voterUnlockStakeWhile :: ProposalStatus -> TxInfo
|
||||||
|
voterUnlockStakeWhile ps =
|
||||||
|
unlockStake
|
||||||
|
ps
|
||||||
|
(VotedFor $ ResultTag 0)
|
||||||
|
42
|
||||||
|
False
|
||||||
|
|
||||||
|
{- | Create an invalid 'TxInfo' that retracts votes using the stake
|
||||||
|
that is used to create the proposal.
|
||||||
|
-}
|
||||||
|
creatorRetractVotesWhile :: ProposalStatus -> TxInfo
|
||||||
|
creatorRetractVotesWhile ps =
|
||||||
|
unlockStake
|
||||||
|
ps
|
||||||
|
Created
|
||||||
|
42
|
||||||
|
True
|
||||||
|
|
||||||
|
{- | Create a 'TxInfo' to unlock the stake that is used to create the propsoal.
|
||||||
|
The 'TxInfo' is valid only if the given proposal status is 'Finished'.
|
||||||
|
-}
|
||||||
|
creatorUnlockStakeWhile :: ProposalStatus -> TxInfo
|
||||||
|
creatorUnlockStakeWhile ps =
|
||||||
|
unlockStake
|
||||||
|
ps
|
||||||
|
Created
|
||||||
|
42
|
||||||
|
False
|
||||||
|
|
||||||
|
{- | Create an invalid 'TxInfo' that tries to retract votes and also unlock a stake
|
||||||
|
which is not locked by the proposal, given the status of the proposal.
|
||||||
|
-}
|
||||||
|
unlockStakeAndRetractVotesUsingIrrelevantStakeWhile :: ProposalStatus -> TxInfo
|
||||||
|
unlockStakeAndRetractVotesUsingIrrelevantStakeWhile ps =
|
||||||
|
unlockStake
|
||||||
|
ps
|
||||||
|
DidNothing
|
||||||
|
42
|
||||||
|
True
|
||||||
|
|
||||||
|
{- | Create an invalid 'TxInfo' that tries to unlock a stake which is not locked by the proposal,
|
||||||
|
given the status of the proposal.
|
||||||
|
-}
|
||||||
|
unlockStakeUsingIrrelevantStakeWhile :: ProposalStatus -> TxInfo
|
||||||
|
unlockStakeUsingIrrelevantStakeWhile ps =
|
||||||
|
unlockStake
|
||||||
|
ps
|
||||||
|
DidNothing
|
||||||
|
42
|
||||||
|
False
|
||||||
|
|
|
||||||
|
|
@ -53,10 +53,16 @@ import Sample.Proposal qualified as Proposal (
|
||||||
advanceProposalSuccess,
|
advanceProposalSuccess,
|
||||||
advancePropsoalWithInvalidOutputStake,
|
advancePropsoalWithInvalidOutputStake,
|
||||||
cosignProposal,
|
cosignProposal,
|
||||||
|
creatorRetractVotesWhile,
|
||||||
|
creatorUnlockStakeWhile,
|
||||||
proposalCreation,
|
proposalCreation,
|
||||||
proposalRef,
|
proposalRef,
|
||||||
stakeRef,
|
stakeRef,
|
||||||
|
unlockStakeAndRetractVotesUsingIrrelevantStakeWhile,
|
||||||
|
unlockStakeUsingIrrelevantStakeWhile,
|
||||||
voteOnProposal,
|
voteOnProposal,
|
||||||
|
voterUnlockStakeAndRetractVotesWhile,
|
||||||
|
voterUnlockStakeWhile,
|
||||||
)
|
)
|
||||||
import Sample.Shared (signer, signer2)
|
import Sample.Shared (signer, signer2)
|
||||||
import Sample.Shared qualified as Shared (proposal, stake)
|
import Sample.Shared qualified as Shared (proposal, stake)
|
||||||
|
|
@ -356,5 +362,249 @@ specs =
|
||||||
(Spending Proposal.proposalRef)
|
(Spending Proposal.proposalRef)
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
, group
|
||||||
|
"unlocking"
|
||||||
|
[ group
|
||||||
|
"legal"
|
||||||
|
[ validatorSucceedsWith
|
||||||
|
"retract votes and unlock stake while voting"
|
||||||
|
(proposalValidator Shared.proposal)
|
||||||
|
( ProposalDatum
|
||||||
|
{ proposalId = ProposalId 0
|
||||||
|
, effects =
|
||||||
|
AssocMap.fromList
|
||||||
|
[ (ResultTag 0, AssocMap.empty)
|
||||||
|
, (ResultTag 1, AssocMap.empty)
|
||||||
|
]
|
||||||
|
, status = VotingReady
|
||||||
|
, cosigners = [signer]
|
||||||
|
, thresholds = def
|
||||||
|
, votes =
|
||||||
|
ProposalVotes
|
||||||
|
( AssocMap.fromList
|
||||||
|
[ (ResultTag 0, 42)
|
||||||
|
, (ResultTag 1, 0)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
, timingConfig = def
|
||||||
|
, startingTime = ProposalStartingTime 0
|
||||||
|
}
|
||||||
|
)
|
||||||
|
(Unlock (ResultTag 0))
|
||||||
|
( ScriptContext
|
||||||
|
(Proposal.voterUnlockStakeAndRetractVotesWhile VotingReady)
|
||||||
|
(Spending Proposal.proposalRef)
|
||||||
|
)
|
||||||
|
, validatorSucceedsWith
|
||||||
|
"unlock the stake that has been used to create the proposal"
|
||||||
|
(proposalValidator Shared.proposal)
|
||||||
|
( ProposalDatum
|
||||||
|
{ proposalId = ProposalId 0
|
||||||
|
, effects =
|
||||||
|
AssocMap.fromList
|
||||||
|
[ (ResultTag 0, AssocMap.empty)
|
||||||
|
, (ResultTag 1, AssocMap.empty)
|
||||||
|
]
|
||||||
|
, status = Finished
|
||||||
|
, cosigners = [signer]
|
||||||
|
, thresholds = def
|
||||||
|
, votes =
|
||||||
|
ProposalVotes
|
||||||
|
( AssocMap.fromList
|
||||||
|
[ (ResultTag 0, 42)
|
||||||
|
, (ResultTag 1, 0)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
, timingConfig = def
|
||||||
|
, startingTime = ProposalStartingTime 0
|
||||||
|
}
|
||||||
|
)
|
||||||
|
(Unlock (ResultTag 0))
|
||||||
|
( ScriptContext
|
||||||
|
(Proposal.creatorUnlockStakeWhile Finished)
|
||||||
|
(Spending Proposal.proposalRef)
|
||||||
|
)
|
||||||
|
, group "unlock stake after voting" $
|
||||||
|
map
|
||||||
|
( \ps ->
|
||||||
|
validatorSucceedsWith
|
||||||
|
(show ps)
|
||||||
|
(proposalValidator Shared.proposal)
|
||||||
|
( ProposalDatum
|
||||||
|
{ proposalId = ProposalId 0
|
||||||
|
, effects =
|
||||||
|
AssocMap.fromList
|
||||||
|
[ (ResultTag 0, AssocMap.empty)
|
||||||
|
, (ResultTag 1, AssocMap.empty)
|
||||||
|
]
|
||||||
|
, status = ps
|
||||||
|
, cosigners = [signer]
|
||||||
|
, thresholds = def
|
||||||
|
, votes =
|
||||||
|
ProposalVotes
|
||||||
|
( AssocMap.fromList
|
||||||
|
[ (ResultTag 0, 42)
|
||||||
|
, (ResultTag 1, 0)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
, timingConfig = def
|
||||||
|
, startingTime = ProposalStartingTime 0
|
||||||
|
}
|
||||||
|
)
|
||||||
|
(Unlock (ResultTag 0))
|
||||||
|
( ScriptContext
|
||||||
|
(Proposal.voterUnlockStakeWhile ps)
|
||||||
|
(Spending Proposal.proposalRef)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
[Locked, Finished]
|
||||||
|
]
|
||||||
|
, group
|
||||||
|
"illegal"
|
||||||
|
[ group "retract votes while the proposal is not voting ready" $
|
||||||
|
map
|
||||||
|
( \ps ->
|
||||||
|
validatorFailsWith
|
||||||
|
(show ps)
|
||||||
|
(proposalValidator Shared.proposal)
|
||||||
|
( ProposalDatum
|
||||||
|
{ proposalId = ProposalId 0
|
||||||
|
, effects =
|
||||||
|
AssocMap.fromList
|
||||||
|
[ (ResultTag 0, AssocMap.empty)
|
||||||
|
, (ResultTag 1, AssocMap.empty)
|
||||||
|
]
|
||||||
|
, status = ps
|
||||||
|
, cosigners = [signer]
|
||||||
|
, thresholds = def
|
||||||
|
, votes =
|
||||||
|
ProposalVotes
|
||||||
|
( AssocMap.fromList
|
||||||
|
[ (ResultTag 0, 42)
|
||||||
|
, (ResultTag 1, 0)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
, timingConfig = def
|
||||||
|
, startingTime = ProposalStartingTime 0
|
||||||
|
}
|
||||||
|
)
|
||||||
|
(Unlock (ResultTag 0))
|
||||||
|
( ScriptContext
|
||||||
|
(Proposal.voterUnlockStakeAndRetractVotesWhile ps)
|
||||||
|
(Spending Proposal.proposalRef)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
[Draft, Locked, Finished]
|
||||||
|
, group
|
||||||
|
"irrelevant stake"
|
||||||
|
$ foldMap
|
||||||
|
( \(f, s) ->
|
||||||
|
map
|
||||||
|
( \ps ->
|
||||||
|
validatorFailsWith
|
||||||
|
(s <> " (" <> show ps <> ")")
|
||||||
|
(proposalValidator Shared.proposal)
|
||||||
|
( ProposalDatum
|
||||||
|
{ proposalId = ProposalId 0
|
||||||
|
, effects =
|
||||||
|
AssocMap.fromList
|
||||||
|
[ (ResultTag 0, AssocMap.empty)
|
||||||
|
, (ResultTag 1, AssocMap.empty)
|
||||||
|
]
|
||||||
|
, status = ps
|
||||||
|
, cosigners = [signer]
|
||||||
|
, thresholds = def
|
||||||
|
, votes =
|
||||||
|
ProposalVotes
|
||||||
|
( AssocMap.fromList
|
||||||
|
[ (ResultTag 0, 42)
|
||||||
|
, (ResultTag 1, 0)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
, timingConfig = def
|
||||||
|
, startingTime = ProposalStartingTime 0
|
||||||
|
}
|
||||||
|
)
|
||||||
|
(Unlock (ResultTag 0))
|
||||||
|
( ScriptContext
|
||||||
|
(f ps)
|
||||||
|
(Spending Proposal.proposalRef)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
[Draft, VotingReady, Locked, Finished]
|
||||||
|
)
|
||||||
|
[ (Proposal.unlockStakeAndRetractVotesUsingIrrelevantStakeWhile, "unlock stake + retract votes")
|
||||||
|
, (Proposal.unlockStakeUsingIrrelevantStakeWhile, "unlock stake")
|
||||||
|
]
|
||||||
|
, group "unlock stake that has been used to create the proposal before finished" $
|
||||||
|
map
|
||||||
|
( \ps ->
|
||||||
|
validatorFailsWith
|
||||||
|
(show ps)
|
||||||
|
(proposalValidator Shared.proposal)
|
||||||
|
( ProposalDatum
|
||||||
|
{ proposalId = ProposalId 0
|
||||||
|
, effects =
|
||||||
|
AssocMap.fromList
|
||||||
|
[ (ResultTag 0, AssocMap.empty)
|
||||||
|
, (ResultTag 1, AssocMap.empty)
|
||||||
|
]
|
||||||
|
, status = ps
|
||||||
|
, cosigners = [signer]
|
||||||
|
, thresholds = def
|
||||||
|
, votes =
|
||||||
|
ProposalVotes
|
||||||
|
( AssocMap.fromList
|
||||||
|
[ (ResultTag 0, 42)
|
||||||
|
, (ResultTag 1, 0)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
, timingConfig = def
|
||||||
|
, startingTime = ProposalStartingTime 0
|
||||||
|
}
|
||||||
|
)
|
||||||
|
(Unlock (ResultTag 0))
|
||||||
|
( ScriptContext
|
||||||
|
(Proposal.creatorUnlockStakeWhile ps)
|
||||||
|
(Spending Proposal.proposalRef)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
[Draft, VotingReady, Locked]
|
||||||
|
, group "creator stake retract votes" $
|
||||||
|
map
|
||||||
|
( \ps ->
|
||||||
|
validatorFailsWith
|
||||||
|
(show ps)
|
||||||
|
(proposalValidator Shared.proposal)
|
||||||
|
( ProposalDatum
|
||||||
|
{ proposalId = ProposalId 0
|
||||||
|
, effects =
|
||||||
|
AssocMap.fromList
|
||||||
|
[ (ResultTag 0, AssocMap.empty)
|
||||||
|
, (ResultTag 1, AssocMap.empty)
|
||||||
|
]
|
||||||
|
, status = ps
|
||||||
|
, cosigners = [signer]
|
||||||
|
, thresholds = def
|
||||||
|
, votes =
|
||||||
|
ProposalVotes
|
||||||
|
( AssocMap.fromList
|
||||||
|
[ (ResultTag 0, 42)
|
||||||
|
, (ResultTag 1, 0)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
, timingConfig = def
|
||||||
|
, startingTime = ProposalStartingTime 0
|
||||||
|
}
|
||||||
|
)
|
||||||
|
(Unlock (ResultTag 0))
|
||||||
|
( ScriptContext
|
||||||
|
(Proposal.creatorRetractVotesWhile ps)
|
||||||
|
(Spending Proposal.proposalRef)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
[Draft, VotingReady, Locked, Finished]
|
||||||
|
]
|
||||||
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,10 @@ Agora/Proposal/validator/advancing/successfully advance to next state/Locked ->
|
||||||
Agora/Proposal/validator/advancing/successfully advance to failed state: timeout/Draft -> Finished,160888965,431112,6394
|
Agora/Proposal/validator/advancing/successfully advance to failed state: timeout/Draft -> Finished,160888965,431112,6394
|
||||||
Agora/Proposal/validator/advancing/successfully advance to failed state: timeout/VotingReady -> Finished,159480054,428407,6395
|
Agora/Proposal/validator/advancing/successfully advance to failed state: timeout/VotingReady -> Finished,159480054,428407,6395
|
||||||
Agora/Proposal/validator/advancing/successfully advance to failed state: timeout/Locked -> Finished,160611032,430811,6395
|
Agora/Proposal/validator/advancing/successfully advance to failed state: timeout/Locked -> Finished,160611032,430811,6395
|
||||||
|
Agora/Proposal/validator/unlocking/legal/retract votes and unlock stake while voting,171592676,462566,6467
|
||||||
|
Agora/Proposal/validator/unlocking/legal/unlock the stake that has been used to create the proposal,149988973,407906,6474
|
||||||
|
Agora/Proposal/validator/unlocking/legal/unlock stake after voting/Locked,149056062,408201,6468
|
||||||
|
Agora/Proposal/validator/unlocking/legal/unlock stake after voting/Finished,149056062,408201,6468
|
||||||
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,29938856,79744,1390
|
Agora/Treasury/Validator/Positive/Allows for effect changes,29938856,79744,1390
|
||||||
|
|
|
||||||
|
Loading…
Add table
Add a link
Reference in a new issue