Merge pull request #204 from Liqwid-Labs/emiflake/update-docs

Update docs
This commit is contained in:
emiflake 2022-10-31 14:09:45 +01:00 committed by GitHub
commit 7ea90750a5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 299 additions and 186 deletions

11
.github/pull_request_template.md vendored Normal file
View file

@ -0,0 +1,11 @@
## Describe your changes
## Relevant issues
## Checklist before requesting a review.
- [ ] I have ensured documentation and testing are thorough.
- [ ] I have updated the changelog.
- [ ] I have read [CONTRIBUTING.md][../CONTRIBUTING.md]
- [ ] I have made sure the CI checks run using `nix run .#ci`.
- [ ] I have followed the code standards to the best of my ability or have documented carefully where and why I haven't.

View file

@ -11,6 +11,7 @@ Please follow the [Git policy](https://liqwid.notion.site/Git-Policy-9a7979b2fd5
This document will make reference to the _Agora core team_. These are the people who work on Agora professionally and will be responsible for maintaining the project in its open source life. They include:
- [Emily Martins](https://github.com/emiflake)
- [Connor Fang](https://github.com/chfanghr)
- [Jack Hodgkinson](https://github.com/jhodgdev)
## Issues
@ -33,7 +34,7 @@ If you wish to work to resolve the issue, the Agora team would invite you to sub
Only those within the core Agora team may contribute work to the project directly. If you wish to work on the project, you must [fork](https://docs.github.com/en/get-started/quickstart/fork-a-repo) the repository and submit your changes to your fork. Instructions for getting started with the project may be found in the [README](./README.md). Once the work on your fork is completed, you may submit a PR [here](https://github.com/Liqwid-Labs/agora/pulls).
Before submitting a PR, please write an issue pertaining to the problem that your PR would solve e.g. a bug in the codebase or a missing feature. Read this document's section on _Issues_ and pay particular heed to the paragraph asking contributors to _look for pre-existing issues_. The prior experiences of existing contributors could save you a significant amount of time and effort. It is possible that a number of issues could be solved by your PR. Please reference any issues that would be ameliorated by your PR - including your own issue, if you have written one - clearly. Please label your PR using GitHub's tagging feature. Please state plainly:
If your PR fixes an issue that isn't a very obvious bug, or has not previously been discussed, please write an issue pertaining to the problem that your PR would solve. Read this document's section on _Issues_ and pay particular heed to the paragraph asking contributors to _look for pre-existing issues_. The prior experiences of existing contributors could save you a significant amount of time and effort. It is possible that a number of issues could be solved by your PR. Please reference any issues that would be ameliorated by your PR - including your own issue, if you have written one - clearly. Please label your PR using GitHub's tagging feature. Please state plainly:
- What your PR achieves.
- How your PR works.
@ -48,17 +49,9 @@ Agora utilises [Plutarch](https://github.com/plutonomicon/plutarch) and your wor
### Continuous integration
For your PR to be merged it must pass three automated checks:
For your PR to be merged it must pass the CI checks.
1. A [`fourmolu`](https://github.com/fourmolu/fourmolu) formatting check.
2. A [`hlint`](https://github.com/ndmitchell/hlint) linting check.
3. A Cabal build check.
Our custom `fourmolu` rules may be found in the [base of the repository](./fourmolu.yaml). You can ensure that your work will pass CI by:
1. Running `make format` from the included `Makefile`.
2. Running `make lint` from the included `Makefile` and applying any recommendations.
3. Ensuring that `cabal build` terminates successfully on your machine in the provided Nix environment.
These can be run locally by running `nix run .#ci`. If you are making a PR through a fork of the repository, they might not be run in CI. When this is the case, please ensure the CI checks run fine locally before you request a review.
## Standards

View file

@ -616,7 +616,8 @@ mkInTimeTimeRange advanceFrom =
+ (def :: ProposalTimingConfig).draftTime
+ (def :: ProposalTimingConfig).votingTime
+ (def :: ProposalTimingConfig).lockingTime
+ (def :: ProposalTimingConfig).executingTime - 1
+ (def :: ProposalTimingConfig).executingTime
- 1
)
Finished -> error "Cannot advance 'Finished' proposal"
@ -632,7 +633,8 @@ mkTooLateTimeRange advanceFrom =
(proposalStartingTime + (def :: ProposalTimingConfig).draftTime + 1)
( proposalStartingTime
+ (def :: ProposalTimingConfig).draftTime
+ (def :: ProposalTimingConfig).votingTime - 1
+ (def :: ProposalTimingConfig).votingTime
- 1
)
-- [S + D + V + L + 1, S + D + V + L + E -1]
VotingReady ->
@ -682,7 +684,8 @@ compPerStakeGTsForDraft :: NumStake -> Tagged GTTag Integer
compPerStakeGTsForDraft nCosigners =
Tagged $
untag (def :: ProposalThresholds).toVoting
`div` fromIntegral nCosigners + 1
`div` fromIntegral nCosigners
+ 1
dummyDatum :: ()
dummyDatum = ()
@ -948,7 +951,8 @@ mkInsufficientCosignsBundle nCosigners nEffects =
insuffcientPerStakeGTs =
Tagged $
untag (def :: ProposalThresholds).toVoting
`div` fromIntegral nCosigners - 1
`div` fromIntegral nCosigners
- 1
template = mkValidToNextStateBundle nCosigners nEffects False Draft
-- * From VotingReady

View file

@ -294,7 +294,8 @@ cosign ps = builder
closedBoundedInterval
(coerce proposalInputDatum.startingTime + 1)
( coerce proposalInputDatum.startingTime
+ proposalInputDatum.timingConfig.draftTime - 1
+ proposalInputDatum.timingConfig.draftTime
- 1
)
sig =

View file

@ -348,7 +348,8 @@ unlock ps = builder
in closedBoundedInterval (lb + 1) (ub - 1)
AfterVoting ->
let lb =
s + (def :: ProposalTimingConfig).draftTime
s
+ (def :: ProposalTimingConfig).draftTime
+ (def :: ProposalTimingConfig).votingTime
ub = lb + (def :: ProposalTimingConfig).lockingTime
in closedBoundedInterval (lb + 1) (ub - 1)

View file

@ -45,8 +45,8 @@ specs =
, inputCollateral 10
, inputTreasury 1 (asset1 10)
]
$ outputTreasury 1 (asset1 7) :
buildReceiversOutputFromDatum datum1
$ outputTreasury 1 (asset1 7)
: buildReceiversOutputFromDatum datum1
)
, effectSucceedsWith
"Simple with multiple treasuries "
@ -120,8 +120,8 @@ specs =
, inputCollateral 10
, inputTreasury 999 (asset1 20)
]
$ outputTreasury 999 (asset1 17) :
buildReceiversOutputFromDatum datum3
$ outputTreasury 999 (asset1 17)
: buildReceiversOutputFromDatum datum3
)
, effectFailsWith
"Prevent transactions besides the withdrawal"

View file

@ -112,10 +112,11 @@ singleAuthorityTokenBurned gatCs inputs mint = unTermCont $ do
PTxInInfo txInInfo -> unTermCont $ do
resolved <- pletC $ pfield @"resolved" # txInInfo
pguardC "While counting GATs at inputs: all GATs must be valid" $
authorityTokensValidIn # gatCs
pguardC "While counting GATs at inputs: all GATs must be valid"
$ authorityTokensValidIn
# gatCs
#$ pfromData
$ resolved
$ resolved
pure . pcon . PSum $
psymbolValueOf

View file

@ -164,7 +164,8 @@ mutateGovernorValidator =
( \inInfo ->
pisScriptAddress
#$ pfield @"address"
#$ pfield @"resolved" # inInfo
#$ pfield @"resolved"
# inInfo
)
# pfromData txInfoF.inputs
@ -192,7 +193,8 @@ mutateGovernorValidator =
, ptraceIfFalse "Can only modify the pinned governor" $
inputF.outRef #== effectDatumF.governorRef
, ptraceIfFalse "Governor validator run" $
pfield @"address" # inputF.resolved
pfield @"address"
# inputF.resolved
#== governorAddress
]
in isGovernorInput
@ -201,10 +203,11 @@ mutateGovernorValidator =
let governorRedeemer =
pfromData $
passertPJust # "Govenor redeemer should be resolved"
passertPJust
# "Govenor redeemer should be resolved"
#$ ptryFromRedeemer @(PAsData PGovernorRedeemer)
# mkRecordConstr PSpending (#_0 .= effectDatumF.governorRef)
# txInfoF.redeemers
# mkRecordConstr PSpending (#_0 .= effectDatumF.governorRef)
# txInfoF.redeemers
pguardC "Spend governor with redeemer MutateGovernor" $
governorRedeemer #== pconstant MutateGovernor

View file

@ -147,7 +147,8 @@ treasuryWithdrawalValidator = plam $
cred <-
pletC $
pfield @"credential"
#$ pfield @"address" # inputF.resolved
#$ pfield @"address"
# inputF.resolved
pure $
foldl1

View file

@ -132,26 +132,33 @@ governorPolicy =
pguardC "Exactly one token should be minted" $
let vMap = pfromData $ pto txInfoF.mint
tnMap =
passertPJust # "GST symbol entry"
#$ plookup # gstSymbol # vMap
passertPJust
# "GST symbol entry"
#$ plookup
# gstSymbol
# vMap
in tnMap #== AssocMap.psingleton # pconstant "" # 1
let governorOutputDatum =
passertPJust # "Governor output should present"
passertPJust
# "Governor output should present"
#$ pfindJust
# plam
( flip (pletFields @'["value", "datum"]) $ \txOutF ->
let isGovernorUTxO =
psymbolValueOf # gstSymbol
# txOutF.value #== 1
# plam
( flip (pletFields @'["value", "datum"]) $ \txOutF ->
let isGovernorUTxO =
psymbolValueOf
# gstSymbol
# txOutF.value
#== 1
governorDatum =
ptrace "Resolve governor datum" $
pfromOutputDatum @PGovernorDatum # txOutF.datum
# txInfoF.datums
in pif isGovernorUTxO (pjust # governorDatum) pnothing
)
# pfromData txInfoF.outputs
governorDatum =
ptrace "Resolve governor datum" $
pfromOutputDatum @PGovernorDatum
# txOutF.datum
# txInfoF.datums
in pif isGovernorUTxO (pjust # governorDatum) pnothing
)
# pfromData txInfoF.outputs
pguardC "Governor output datum valid" $
pisGovernorDatumValid # governorOutputDatum
@ -288,10 +295,11 @@ governorValidator =
let governorInput =
pfield @"resolved"
#$ passertPJust # "Malformed script context: own input not found"
#$ passertPJust
# "Malformed script context: own input not found"
#$ pfindTxInByTxOutRef
# governorInputRef
# txInfoF.inputs
# governorInputRef
# txInfoF.inputs
governorInputF <- pletFieldsC @'["address", "value"] governorInput
@ -301,7 +309,7 @@ governorValidator =
pletC $
passertPJust
# "Own output should present"
#$ pfindJust
#$ pfindJust
# plam
( flip pletAll $ \outputF ->
let isGovernorUTxO =
@ -334,7 +342,8 @@ governorValidator =
let isStakeUTxO =
psymbolValueOf
# sstSymbol
# txOutF.value #== 1
# txOutF.value
#== 1
datum =
ptrace "Resolve stake input datum" $
@ -349,8 +358,12 @@ governorValidator =
plam $
flip (pletFields @'["value", "datum", "address"]) $ \txOutF ->
let isProposalUTxO =
txOutF.address #== pdata proposalValidatorAddress
#&& psymbolValueOf # pstSymbol # txOutF.value #== 1
txOutF.address
#== pdata proposalValidatorAddress
#&& psymbolValueOf
# pstSymbol
# txOutF.value
#== 1
proposalDatum =
ptrace "Resolve proposal output datum" $
@ -375,13 +388,16 @@ governorValidator =
expectedNewDatum =
mkRecordConstr
PGovernorDatum
( #proposalThresholds .= governorInputDatumF.proposalThresholds
.& #nextProposalId .= pdata expectedNextProposalId
.& #proposalTimings .= governorInputDatumF.proposalTimings
( #proposalThresholds
.= governorInputDatumF.proposalThresholds
.& #nextProposalId
.= pdata expectedNextProposalId
.& #proposalTimings
.= governorInputDatumF.proposalTimings
.& #createProposalTimeRangeMaxWidth
.= governorInputDatumF.createProposalTimeRangeMaxWidth
.= governorInputDatumF.createProposalTimeRangeMaxWidth
.& #maximumProposalsPerStake
.= governorInputDatumF.maximumProposalsPerStake
.= governorInputDatumF.maximumProposalsPerStake
)
pguardC "Only next proposal id gets advanced" $
@ -405,15 +421,17 @@ governorValidator =
-- and the value it contains meets the requirement.
let stakeInputDatum =
passertPJust # "Stake input should present"
passertPJust
# "Stake input should present"
#$ pfindJust
# plam ((getStakeDatum #) . (pfield @"resolved" #))
# pfromData txInfoF.inputs
# plam ((getStakeDatum #) . (pfield @"resolved" #))
# pfromData txInfoF.inputs
stakeInputDatumF <- pletAllC stakeInputDatum
pguardC "Proposals created by the stake must not exceed the limit" $
pnumCreatedProposals # stakeInputDatumF.lockedBy
pnumCreatedProposals
# stakeInputDatumF.lockedBy
#< governorInputDatumF.maximumProposalsPerStake
let gtThreshold =
@ -428,10 +446,11 @@ governorValidator =
-- and the datum it carries is legal.
let proposalOutputDatum =
passertPJust # "Proposal output should present"
passertPJust
# "Proposal output should present"
#$ pfindJust
# getProposalDatum
# pfromData txInfoF.outputs
# getProposalDatum
# pfromData txInfoF.outputs
proposalOutputDatumF <- pletAllC proposalOutputDatum
@ -458,8 +477,10 @@ governorValidator =
# txInfoF.validRange
# proposalOutputDatumF.startingTime
, ptraceIfFalse "copy over configurations" $
proposalOutputDatumF.thresholds #== governorInputDatumF.proposalThresholds
#&& proposalOutputDatumF.timingConfig #== governorInputDatumF.proposalTimings
proposalOutputDatumF.thresholds
#== governorInputDatumF.proposalThresholds
#&& proposalOutputDatumF.timingConfig
#== governorInputDatumF.proposalTimings
]
pure $ popaque $ pconstant ()
@ -475,10 +496,11 @@ governorValidator =
(psymbolValueOf # pstSymbol #$ pvalueSpent # txInfoF.inputs) #== 1
let proposalInputDatum =
passertPJust # "Proposal input not found"
passertPJust
# "Proposal input not found"
#$ pfindJust
# plam ((getProposalDatum #) . (pfield @"resolved" #))
# pfromData txInfoF.inputs
# plam ((getProposalDatum #) . (pfield @"resolved" #))
# pfromData txInfoF.inputs
proposalInputDatumF <-
pletFieldsC @'["effects", "status", "thresholds", "votes"]
@ -506,19 +528,25 @@ governorValidator =
let isAuthorityUTxO =
psymbolValueOf
# atSymbol
# outputF.value #== 1
# outputF.value
#== 1
handleAuthorityUTxO =
unTermCont $ do
receiverScriptHash <-
pletC $
passertPJust # "GAT receiver should be a script"
#$ pscriptHashFromAddress # outputF.address
passertPJust
# "GAT receiver should be a script"
#$ pscriptHashFromAddress
# outputF.address
effect <-
pletAllC $
passertPJust # "Receiver should be in the effect group"
#$ AssocMap.plookup # receiverScriptHash # effectGroup
passertPJust
# "Receiver should be in the effect group"
#$ AssocMap.plookup
# receiverScriptHash
# effectGroup
let tagToken =
pmaybeData
@ -529,7 +557,8 @@ governorValidator =
valueGATCorrect =
passetClassValueOf
# gatAssetClass
# outputF.value #== 1
# outputF.value
#== 1
let hasCorrectDatum =
effect.datumHash #== pfromDatumHash # outputF.datum
@ -555,8 +584,8 @@ governorValidator =
actualReceivers =
psort
#$ pmapMaybe
# getReceiverScriptHash
# pfromData txInfoF.outputs
# getReceiverScriptHash
# pfromData txInfoF.outputs
expectedReceivers = pkeys @PList # effectGroup

View file

@ -241,7 +241,7 @@ proposalValidator =
pfield @"resolved"
#$ passertPJust
# "Own input should present"
#$ pfindTxInByTxOutRef
#$ pfindTxInByTxOutRef
# propsalInputRef
# txInfoF.inputs
@ -261,40 +261,43 @@ proposalValidator =
-- We can handle only one proposal under current design.
proposalOutputDatum <-
pletC $
passertPJust # "proposal input should present"
passertPJust
# "proposal input should present"
#$ pfindJust
# plam
( flip pletAll $ \outputF ->
let isProposalUTxO =
foldl1
(#&&)
[ ptraceIfFalse "Own by proposal validator" $
outputF.address #== proposalInputF.address
, ptraceIfFalse "Has proposal ST" $
psymbolValueOf # pstSymbol # outputF.value #== 1
]
# plam
( flip pletAll $ \outputF ->
let isProposalUTxO =
foldl1
(#&&)
[ ptraceIfFalse "Own by proposal validator" $
outputF.address #== proposalInputF.address
, ptraceIfFalse "Has proposal ST" $
psymbolValueOf # pstSymbol # outputF.value #== 1
]
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
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
--------------------------------------------------------------------------
getTimingRelation' <-
pletC $
let currentTime =
passertPJust # "Current time should be resolved"
#$ currentProposalTime # txInfoF.validRange
passertPJust
# "Current time should be resolved"
#$ currentProposalTime
# txInfoF.validRange
in pgetRelation
# proposalInputDatumF.timingConfig
# proposalInputDatumF.startingTime
@ -321,7 +324,8 @@ proposalValidator =
stake =
pfromData $
-- If we can't resolve the stake datum, error out.
passertPJust # "Stake datum should present"
passertPJust
# "Stake datum should present"
-- Use inline datum to avoid extra map lookup.
#$ ptryFromOutputDatum @(PAsData PStakeDatum)
# txOutF.datum
@ -370,7 +374,8 @@ proposalValidator =
+ punsafeCoerce
(pfromData stakeF.stakedAmount)
, orderedOwners =
pcons # stakeF.owner
pcons
# stakeF.owner
# ctxF.orderedOwners
}
@ -443,14 +448,22 @@ proposalValidator =
let expectedDatum =
mkRecordConstr
PProposalDatum
( #proposalId .= proposalInputDatumF.proposalId
.& #effects .= proposalInputDatumF.effects
.& #status .= proposalInputDatumF.status
.& #cosigners .= pdata updatedSigs
.& #thresholds .= proposalInputDatumF.thresholds
.& #votes .= proposalInputDatumF.votes
.& #timingConfig .= proposalInputDatumF.timingConfig
.& #startingTime .= proposalInputDatumF.startingTime
( #proposalId
.= proposalInputDatumF.proposalId
.& #effects
.= proposalInputDatumF.effects
.& #status
.= proposalInputDatumF.status
.& #cosigners
.= pdata updatedSigs
.& #thresholds
.= proposalInputDatumF.thresholds
.& #votes
.= proposalInputDatumF.votes
.& #timingConfig
.= proposalInputDatumF.timingConfig
.& #startingTime
.= proposalInputDatumF.startingTime
)
pguardC "Signatures are correctly added to cosignature list" $
@ -471,8 +484,8 @@ proposalValidator =
pnot
#$ pisVoter
#$ pgetStakeRoles
# proposalInputDatumF.proposalId
# stakeF.lockedBy
# proposalInputDatumF.proposalId
# stakeF.lockedBy
pure $ pcon $ PSum $ pfromData stakeF.stakedAmount
)
@ -510,14 +523,22 @@ proposalValidator =
expectedProposalOut =
mkRecordConstr
PProposalDatum
( #proposalId .= proposalInputDatumF.proposalId
.& #effects .= proposalInputDatumF.effects
.& #status .= proposalInputDatumF.status
.& #cosigners .= proposalInputDatumF.cosigners
.& #thresholds .= proposalInputDatumF.thresholds
.& #votes .= pdata expectedNewVotes
.& #timingConfig .= proposalInputDatumF.timingConfig
.& #startingTime .= proposalInputDatumF.startingTime
( #proposalId
.= proposalInputDatumF.proposalId
.& #effects
.= proposalInputDatumF.effects
.& #status
.= proposalInputDatumF.status
.& #cosigners
.= proposalInputDatumF.cosigners
.& #thresholds
.= proposalInputDatumF.thresholds
.& #votes
.= pdata expectedNewVotes
.& #timingConfig
.= proposalInputDatumF.timingConfig
.& #startingTime
.= proposalInputDatumF.startingTime
)
pguardC "Output proposal should be valid" $
@ -570,7 +591,8 @@ proposalValidator =
-- The votes can only change when the proposal still allows voting.
shouldUpdateVotes =
currentStatus #== pconstant VotingReady
currentStatus
#== pconstant VotingReady
#&& inVotingPeriod
pguardC "Proposal output correct" $
@ -580,14 +602,22 @@ proposalValidator =
expectedProposalOut =
mkRecordConstr
PProposalDatum
( #proposalId .= proposalInputDatumF.proposalId
.& #effects .= proposalInputDatumF.effects
.& #status .= proposalInputDatumF.status
.& #cosigners .= proposalInputDatumF.cosigners
.& #thresholds .= proposalInputDatumF.thresholds
.& #votes .= pdata expectedVotes
.& #timingConfig .= proposalInputDatumF.timingConfig
.& #startingTime .= proposalInputDatumF.startingTime
( #proposalId
.= proposalInputDatumF.proposalId
.& #effects
.= proposalInputDatumF.effects
.& #status
.= proposalInputDatumF.status
.& #cosigners
.= proposalInputDatumF.cosigners
.& #thresholds
.= proposalInputDatumF.thresholds
.& #votes
.= pdata expectedVotes
.& #timingConfig
.= proposalInputDatumF.timingConfig
.& #startingTime
.= proposalInputDatumF.startingTime
)
in ptraceIfFalse "Update votes" $
expectedProposalOut #== proposalOutputDatum
@ -609,14 +639,22 @@ proposalValidator =
let expectedProposalOutputDatum =
mkRecordConstr
PProposalDatum
( #proposalId .= proposalInputDatumF.proposalId
.& #effects .= proposalInputDatumF.effects
.& #status .= pdata proposalOutputStatus
.& #cosigners .= proposalInputDatumF.cosigners
.& #thresholds .= proposalInputDatumF.thresholds
.& #votes .= proposalInputDatumF.votes
.& #timingConfig .= proposalInputDatumF.timingConfig
.& #startingTime .= proposalInputDatumF.startingTime
( #proposalId
.= proposalInputDatumF.proposalId
.& #effects
.= proposalInputDatumF.effects
.& #status
.= pdata proposalOutputStatus
.& #cosigners
.= proposalInputDatumF.cosigners
.& #thresholds
.= proposalInputDatumF.thresholds
.& #votes
.= proposalInputDatumF.votes
.& #timingConfig
.= proposalInputDatumF.timingConfig
.& #startingTime
.= proposalInputDatumF.startingTime
)
in proposalOutputDatum #== expectedProposalOutputDatum
@ -652,10 +690,12 @@ proposalValidator =
pguardC "Proposal status set to Locked" $
proposalOutputStatus #== pconstant Locked
pguardC "Winner outcome not found" $
pisJust #$ pwinner' # proposalInputDatumF.votes
pguardC "Winner outcome not found"
$ pisJust
#$ pwinner'
# proposalInputDatumF.votes
#$ punsafeCoerce
$ pfromData thresholdsF.execute
$ pfromData thresholdsF.execute
-- Too late: failed proposal, status set to 'Finished'.
PAfter ->
pguardC "Proposal should fail: not on time" $

View file

@ -85,7 +85,8 @@ pbatchUpdateInputs ::
)
pbatchUpdateInputs = phoistAcyclic $
plam $ \f -> flip pmatch $ \ctxF ->
pnull #$ pfoldr
pnull
#$ pfoldr
# (pmustDeleteBy # f)
# ctxF.stakeOutputDatums
# ctxF.stakeInputDatums
@ -135,10 +136,14 @@ ponlyLocksUpdated = phoistAcyclic $
expected =
mkRecordConstr
PStakeDatum
( #stakedAmount .= iF.stakedAmount
.& #owner .= iF.owner
.& #delegatedTo .= iF.delegatedTo
.& #lockedBy .= pdata newLocks
( #stakedAmount
.= iF.stakedAmount
.& #owner
.= iF.owner
.& #delegatedTo
.= iF.delegatedTo
.& #lockedBy
.= pdata newLocks
)
in expected #== o
@ -202,8 +207,10 @@ ppermitVote = pvoteHelper #$ phoistAcyclic $
PVote ((pfromData . (pfield @"resultTag" #)) -> voteFor) ->
mkRecordConstr
PVoted
( #votedOn .= pdata pid
.& #votedFor .= pdata voteFor
( #votedOn
.= pdata pid
.& #votedFor
.= pdata voteFor
)
PCosign _ ->
withOnlyOneStakeInput
@ -306,10 +313,14 @@ pdelegateHelper = phoistAcyclic $
( \i o -> pletAll i $ \iF ->
mkRecordConstr
PStakeDatum
( #stakedAmount .= iF.stakedAmount
.& #owner .= iF.owner
.& #delegatedTo .= pdata newDelegate
.& #lockedBy .= iF.lockedBy
( #stakedAmount
.= iF.stakedAmount
.& #owner
.= iF.owner
.& #delegatedTo
.= pdata newDelegate
.& #lockedBy
.= iF.lockedBy
)
#== o
)
@ -399,10 +410,14 @@ pdepositWithdraw = phoistAcyclic $
let expectedDatum =
mkRecordConstr
PStakeDatum
( #stakedAmount .= pdata newStakedAmount
.& #owner .= stakeInputDatumF.owner
.& #delegatedTo .= stakeInputDatumF.delegatedTo
.& #lockedBy .= stakeInputDatumF.lockedBy
( #stakedAmount
.= pdata newStakedAmount
.& #owner
.= stakeInputDatumF.owner
.& #delegatedTo
.= stakeInputDatumF.delegatedTo
.& #lockedBy
.= stakeInputDatumF.lockedBy
)
pguardC "Valid output datum" $ expectedDatum #== stakeOutputDatum

View file

@ -152,7 +152,8 @@ stakePolicy =
PPair mintedST burntST <-
pmatchC $
pfromJust #$ psymbolValueOf'
pfromJust
#$ psymbolValueOf'
# ownSymbol
# txInfoF.mint
@ -174,7 +175,7 @@ stakePolicy =
let scriptOutputWithStakeST =
passertPJust
# "Output to script not found"
#$ pfind
#$ pfind
# plam
( \output -> unTermCont $ do
outputF <- pletFieldsC @'["value", "address"] output
@ -204,7 +205,9 @@ stakePolicy =
foldl1
(#&&)
[ ptraceIfFalse "Stake ouput has expected amount of stake token" $
passetClassValueOf # (ptoScottEncoding # gstClass) # outputF.value
passetClassValueOf
# (ptoScottEncoding # gstClass)
# outputF.value
#== pto (pfromData datumF.stakedAmount)
, ptraceIfFalse "Stake Owner should sign the transaction" $
pauthorizedBy
@ -263,15 +266,16 @@ mkStakeValidator impl sstSymbol pstClass gstClass =
let validatedInput =
pfield @"resolved"
#$ passertPJust
# "Malformed script context: validated input not found"
# "Malformed script context: validated input not found"
#$ pfindTxInByTxOutRef
# (pfield @"_0" # stakeInputRef)
# txInfoF.inputs
# (pfield @"_0" # stakeInputRef)
# txInfoF.inputs
stakeValidatorCredential <-
pletC $
pfield @"credential"
#$ pfield @"address" # validatedInput
#$ pfield @"address"
# validatedInput
let sstName = pvalidatorHashToTokenName #$ pmatch stakeValidatorCredential $
\case
@ -288,7 +292,8 @@ mkStakeValidator impl sstSymbol pstClass gstClass =
plam $
flip (pletFields @'["value", "datum", "address"]) $ \txOutF ->
pmatch
( pcompareBy # pfromOrd
( pcompareBy
# pfromOrd
# (passetClassValueOf # sstClass # txOutF.value)
# 1
)
@ -348,10 +353,12 @@ mkStakeValidator impl sstSymbol pstClass gstClass =
pmatch p $ \(PPair allHaveSameOwner allHaveSameDelegatee) ->
let allHaveSameOwner' =
allHaveSameOwner
#&& dF.owner #== firstStakeInputDatumF.owner
#&& dF.owner
#== firstStakeInputDatumF.owner
allHaveSameDelegatee' =
allHaveSameDelegatee
#&& dF.delegatedTo #== firstStakeInputDatumF.delegatedTo
#&& dF.delegatedTo
#== firstStakeInputDatumF.delegatedTo
in pcon $ PPair allHaveSameOwner' allHaveSameDelegatee'
)
# pcon (PPair (pconstant True) (pconstant True))
@ -359,14 +366,15 @@ mkStakeValidator impl sstSymbol pstClass gstClass =
let ownerSignsTransaction =
allHaveSameOwner
#&& authorizedBy # firstStakeInputDatumF.owner
#&& authorizedBy
# firstStakeInputDatumF.owner
delegateSignsTransaction =
allHaveSameDelegatee
#&& pmaybeData
# pconstant False
# plam ((authorizedBy #) . pfromData)
# pfromData firstStakeInputDatumF.delegatedTo
# pconstant False
# plam ((authorizedBy #) . pfromData)
# pfromData firstStakeInputDatumF.delegatedTo
signedBy =
pif
@ -375,7 +383,7 @@ mkStakeValidator impl sstSymbol pstClass gstClass =
$ pif
delegateSignsTransaction
(pcon PSignedByDelegate)
$ pcon PUnknownSig
$ pcon PUnknownSig
sigContext <-
pletC $
@ -427,7 +435,8 @@ mkStakeValidator impl sstSymbol pstClass gstClass =
let isProposalUTxO =
passetClassValueOf
# pstClass
# txOutF.value #== 1
# txOutF.value
#== 1
proposalDatum =
pfromData $
pfromOutputDatum @(PAsData PProposalDatum)
@ -442,8 +451,11 @@ mkStakeValidator impl sstSymbol pstClass gstClass =
pcon $
PNewProposal $
pfield @"proposalId"
#$ passertPJust # "Proposal output should present"
#$ pfindJust # getProposalDatum # pfromData txInfoF.outputs
#$ passertPJust
# "Proposal output should present"
#$ pfindJust
# getProposalDatum
# pfromData txInfoF.outputs
spendProposalContext =
let getProposalRedeemer = plam $ \ref ->
@ -451,7 +463,7 @@ mkStakeValidator impl sstSymbol pstClass gstClass =
pto $
passertPJust
# "Malformed script context: propsoal input not found in redeemer map"
#$ plookup
#$ plookup
# pcon
( PSpending $
pdcons @_0
@ -511,10 +523,10 @@ mkStakeValidator impl sstSymbol pstClass gstClass =
txInfo
noMetadataContext <-
pletC $
mkRedeemerhandlerContext
pletC
$ mkRedeemerhandlerContext
#$ pcon
$ PNoMetadata
$ PNoMetadata
--------------------------------------------------------------------------
@ -535,7 +547,8 @@ mkStakeValidator impl sstSymbol pstClass gstClass =
#$ pcon
$ PSetDelegateTo pkh
PDepositWithdraw ((pfield @"delta" #) -> delta) ->
impl.onDepositWithdraw #$ mkRedeemerhandlerContext
impl.onDepositWithdraw
#$ mkRedeemerhandlerContext
#$ pcon
$ PDepositWithdrawDelta delta

8
flake.lock generated
View file

@ -540,11 +540,11 @@
]
},
"locked": {
"lastModified": 1665587728,
"narHash": "sha256-Cz2594dfFxEGB3gCuXlQPGYtiQA7QTviBaUktoYrq9I=",
"owner": "github:Liqwid-Labs",
"lastModified": 1666695559,
"narHash": "sha256-v8DcNma4hAgLCbPHpsxNYzeMURfbxh20VXfFzUED6bs=",
"owner": "Liqwid-Labs",
"repo": "liqwid-nix",
"rev": "c17fef5826ae9e329818018a09302c69fee9a83c",
"rev": "7add1f24e9360e96b2bab4a1fc7929d4fa649439",
"type": "github"
},
"original": {

View file

@ -163,6 +163,7 @@
liqwid-nix.enableCabalFormatCheck
liqwid-nix.enableNixFormatCheck
liqwid-nix.addBuildChecks
liqwid-nix.addCommonRunScripts
(liqwid-nix.addCommandLineTools (pkgs: _: [
pkgs.haskellPackages.hasktags
]))