Use liqwid-script-export

commit ec70bfd539fe2e27fd48f5f76395400287ac72d7
Author: Seungheon Oh <seungheon.ooh@gmail.com>
Date:   Tue Oct 18 18:58:59 2022 -0500

    use LSE

commit 25fff9b3ad1f2dde4cd7cf36977530b06a87d23c
Merge: 01cd3aa a5567ea
Author: Seungheon Oh <seungheon.ooh@gmail.com>
Date:   Tue Oct 18 18:17:45 2022 -0500

    Merge branch 'staging' into seungheonoh/ply

commit 01cd3aa7a235e6fe6658246ca1026fa26dc71a83
Author: Hongrui Fang <chfanghr@gmail.com>
Date:   Tue Oct 11 12:02:03 2022 +0800

    update benchmark

commit a8513244892ce33cfdc9edf8cd501c4985ae8008
Author: Hongrui Fang <chfanghr@gmail.com>
Date:   Tue Oct 11 11:59:22 2022 +0800

    fix tests

commit 20ca40823485c2e2f78253643cf4453ac7b7ddd5
Author: Hongrui Fang <chfanghr@gmail.com>
Date:   Tue Oct 11 11:57:37 2022 +0800

    better import

commit a19fe49424210891bd03db71e4083fc1e0edfd98
Author: Hongrui Fang <chfanghr@gmail.com>
Date:   Tue Oct 11 11:08:20 2022 +0800

    update flake inputs

commit c93b21f1f9441e5c6f54525bf7c6a54757ec36cc
Author: Seungheon Oh <seungheon.ooh@gmail.com>
Date:   Mon Oct 10 12:54:12 2022 -0500

    tried to make tests pass

commit 1046ae1237299a33c58b48661bdb6d325a22147e
Merge: 2bf4e36 e2bd48b
Author: Seungheon Oh <seungheon.ooh@gmail.com>
Date:   Mon Oct 10 12:18:48 2022 -0500

    Merge branch 'staging' into seungheonoh/ply

commit 2bf4e3627c1b229f58078695082da85c80efd560
Author: Seungheon Oh <seungheon.ooh@gmail.com>
Date:   Mon Oct 10 10:48:36 2022 -0500

    remove junkpile

commit a1dbc9ad9e531fe0d0a0480c4aef9cf9ffa90f1d
Author: Seungheon Oh <seungheon.ooh@gmail.com>
Date:   Mon Oct 10 10:47:25 2022 -0500

    versions

commit 4542a06ac733858297d3a48c53368fad19dedc43
Author: Seungheon Oh <seungheon.ooh@gmail.com>
Date:   Thu Oct 6 22:57:48 2022 -0500

    script exporting interface

commit 6bd8c1a1d57e4bf9dc25c3068a9c8eae6bf6a19d
Author: Seungheon Oh <seungheon.ooh@gmail.com>
Date:   Thu Oct 6 22:58:41 2022 -0500

    fixed tests

commit d3ce2cf95633d336f3e621833677bd5bf10ee2c8
Author: Seungheon Oh <seungheon.ooh@gmail.com>
Date:   Sun Oct 2 00:55:18 2022 -0500

    fixed tests

commit 1ae64c9f692652b77b0506013853b2ba44267c65
Author: Seungheon Oh <seungheon.ooh@gmail.com>
Date:   Sat Oct 1 13:28:20 2022 -0500

    linker

commit db88cb75c7b74843141ad8ab4e6522b66d0dcfbc
Author: Seungheon Oh <seungheon.ooh@gmail.com>
Date:   Sat Oct 1 01:03:50 2022 -0500

    exporting scripts

commit 6389fce28e885a8a7f8669629c266f59c0edb51f
Author: Seungheon Oh <seungheon.ooh@gmail.com>
Date:   Sat Oct 1 00:51:49 2022 -0500

    made scripts parameterized on the script level

commit aea1e518a8890550bdebd0e5251da11d915c53a9
Author: Seungheon Oh <seungheon.ooh@gmail.com>
Date:   Wed Sep 28 19:53:29 2022 -0500

    Use `TypedScriptEnvelope` for `Agora.Bootstrap`
This commit is contained in:
Seungheon Oh 2022-10-18 18:59:38 -05:00
parent a5567eaa5e
commit 275d3a5b69
38 changed files with 8614 additions and 2330 deletions

View file

@ -13,12 +13,6 @@ module Agora.Stake.Scripts (
import Agora.Credential (authorizationContext, pauthorizedBy)
import Agora.Proposal (PProposalDatum, PProposalRedeemer)
import Agora.SafeMoney (GTTag)
import Agora.Scripts (
AgoraScripts,
proposalSTAssetClass,
stakeSTSymbol,
)
import Agora.Stake (
PProposalContext (
PNewProposal,
@ -62,16 +56,13 @@ import Agora.Stake.Redeemers (
pretractVote,
)
import Agora.Utils (passert, pmapMaybe)
import Data.Tagged (Tagged (Tagged))
import Plutarch.Api.V1 (
KeyGuarantees (Sorted),
PCredential (PPubKeyCredential, PScriptCredential),
PCurrencySymbol,
PTokenName,
)
import Plutarch.Api.V1.AssocMap (plookup)
import Plutarch.Api.V1.Value (PValue)
import Plutarch.Api.V2 (
AmountGuarantees,
PMintingPolicy,
PScriptPurpose (PMinting, PSpending),
PTxInfo,
@ -79,7 +70,7 @@ import Plutarch.Api.V2 (
PValidator,
)
import Plutarch.Extra.AssetClass (
passetClass,
PAssetClass,
passetClassValueOf,
pvalueOf,
)
@ -114,10 +105,8 @@ import Plutarch.Extra.Value (
import Plutarch.Num (PNum (pnegate))
import Plutarch.SafeMoney (
pvalueDiscrete,
pvalueDiscrete',
)
import Plutarch.Unsafe (punsafeCoerce)
import PlutusLedgerApi.V1.Value (AssetClass (AssetClass))
import Prelude hiding (Num ((+)))
{- | Policy for Stake state threads.
@ -137,14 +126,18 @@ import Prelude hiding (Num ((+)))
- Check that exactly one state thread is burned.
- Check that datum at state thread is valid and not locked.
@since 0.1.0
== Arguments
Following arguments should be provided(in this order):
1. governor ST assetclass
@since 1.0.0
-}
stakePolicy ::
-- | The (governance) token that a Stake can store.
Tagged GTTag AssetClass ->
ClosedTerm PMintingPolicy
stakePolicy gtClassRef =
plam $ \_redeemer ctx' -> unTermCont $ do
ClosedTerm (PAssetClass :--> PMintingPolicy)
stakePolicy =
plam $ \gstClass _redeemer ctx' -> unTermCont $ do
ctx <- pletFieldsC @'["txInfo", "purpose"] ctx'
txInfo <- pletC $ ctx.txInfo
let _a :: Term _ PTxInfo
@ -226,7 +219,7 @@ stakePolicy gtClassRef =
let hasExpectedStake =
ptraceIfFalse "Stake ouput has expected amount of stake token" $
pvalueDiscrete' gtClassRef # outputF.value #== datumF.stakedAmount
pvalueDiscrete # gstClass # outputF.value #== datumF.stakedAmount
let ownerSignsTransaction =
ptraceIfFalse "Stake Owner should sign the transaction" $
pauthorizedBy
@ -243,338 +236,319 @@ stakePolicy gtClassRef =
{- | Create a stake validator, given the implementation of stake redeemers.
== Arguments
Following arguments should be provided(in this order):
1. stake ST symbol
2. proposal ST assetclass
3. governor ST assetclass
@since 1.0.0
-}
mkStakeValidator ::
StakeRedeemerImpl ->
AgoraScripts ->
Tagged GTTag AssetClass ->
ClosedTerm PValidator
mkStakeValidator
impl
as
(Tagged (AssetClass (gtSym, gtTn))) =
plam $ \_datum redeemer ctx -> unTermCont $ do
let sstValueOf ::
( forall (ag :: AmountGuarantees) (s :: S).
Term s (PValue 'Sorted ag :--> PInteger)
)
sstValueOf =
phoistAcyclic $
psymbolValueOf # pconstant (stakeSTSymbol as)
--------------------------------------------------------------------------
ctxF <- pletFieldsC @'["txInfo", "purpose"] ctx
txInfo <- pletC $ pfromData ctxF.txInfo
txInfoF <-
pletFieldsC
@'[ "inputs"
, "referenceInputs"
, "outputs"
, "mint"
, "validRange"
, "signatories"
, "redeemers"
, "datums"
]
txInfo
--------------------------------------------------------------------------
PSpending stakeInputRef <- pmatchC $ pfromData ctxF.purpose
let validatedInput =
pfield @"resolved"
#$ passertPJust
# "Malformed script context: validated input not found"
#$ pfindTxInByTxOutRef
# (pfield @"_0" # stakeInputRef)
# txInfoF.inputs
stakeValidatorCredential =
pfield @"credential"
#$ pfield @"address" # validatedInput
--------------------------------------------------------------------------
-- Returns stake datum if the given UTxO is a stake UTxO.
getStakeDatum :: Term _ (PTxOut :--> PMaybe PStakeDatum) <-
pletC $
plam $
flip (pletFields @'["value", "datum", "address"]) $ \txOutF ->
pmatch
( pcompareBy # pfromOrd
# (sstValueOf # txOutF.value)
# 1
)
$ \case
-- > 1
PGT -> ptraceError "More than one SST in one UTxO"
-- 1
PEQ ->
let ownerCredential = pfield @"credential" # txOutF.address
isOwnedByStakeValidator =
ownerCredential #== stakeValidatorCredential
datum =
ptrace "Resolve stake datum" $
pfromData $
pfromOutputDatum @(PAsData PStakeDatum)
# txOutF.datum
# txInfoF.datums
in passert
"Should owned by stake validator"
isOwnedByStakeValidator
(pjust # datum)
-- 0
PLT -> pnothing
--------------------------------------------------------------------------
-- Find all stake inputs.
stakeInputDatums <-
pletC $
pmapMaybe
# plam ((getStakeDatum #) . (pfield @"resolved" #))
# pfromData txInfoF.inputs
--------------------------------------------------------------------------
-- Assemble the signature context.
firstStakeInputDatumF <-
pletFieldsC @'["owner", "delegatedTo"] $
phead # stakeInputDatums
restOfStakeInputDatums <- pletC $ ptail # stakeInputDatums
authorizedBy <- pletC $ pauthorizedBy # authorizationContext txInfoF
PPair allHaveSameOwner allHaveSameDelegatee <-
pmatchC $
pfoldr
# plam
( \d p -> unTermCont $ do
dF <- pletFieldsC @'["owner", "delegatedTo"] d
pure $
pmatch p $ \(PPair allHaveSameOwner allHaveSameDelegatee) ->
let allHaveSameOwner' =
allHaveSameOwner
#&& dF.owner #== firstStakeInputDatumF.owner
allHaveSameDelegatee' =
allHaveSameDelegatee
#&& dF.delegatedTo #== firstStakeInputDatumF.delegatedTo
in pcon $ PPair allHaveSameOwner' allHaveSameDelegatee'
)
# pcon (PPair (pconstant True) (pconstant True))
# restOfStakeInputDatums
let ownerSignsTransaction =
allHaveSameOwner
#&& authorizedBy # firstStakeInputDatumF.owner
delegateSignsTransaction =
allHaveSameDelegatee
#&& pmaybeData
# pconstant False
# plam ((authorizedBy #) . pfromData)
# pfromData firstStakeInputDatumF.delegatedTo
signedBy =
pif
ownerSignsTransaction
(pcon PSignedByOwner)
$ pif
delegateSignsTransaction
(pcon PSignedByDelegate)
$ pcon PUnknownSig
sigContext <-
pletC $
pcon $
PSigContext
firstStakeInputDatumF.owner
firstStakeInputDatumF.delegatedTo
signedBy
--------------------------------------------------------------------------
-- Find all stake outputs.
let gtAssetClass = passetClass # pconstant gtSym # pconstant gtTn
-- First step of validating stake outputs. We make sure that every stake
-- output UTxO carries correct amount of GTs specified by its datum.
--
-- Note that non-GT assets are treated transparently.
stakeOutputDatums <-
pletC $
pmapMaybe
# plam
( \output ->
let validateGT = plam $ \stakeDatum ->
let expected = pfield @"stakedAmount" # stakeDatum
actual =
pvalueDiscrete
# gtAssetClass
# (pfield @"value" # output)
in pif
(expected #== actual)
stakeDatum
(ptraceError "Unmatched GT value")
in pfmap
# validateGT
# (getStakeDatum # output)
)
# pfromData txInfoF.outputs
--------------------------------------------------------------------------
mintedST <- pletC $ sstValueOf # txInfoF.mint
pguardC "No new SST minted" $
foldl1
(#||)
[ ptraceIfTrue "All stakes burnt" $
mintedST #< 0 #&& pnull # stakeOutputDatums
, ptraceIfTrue "Nothing burnt" $
mintedST #== 0
ClosedTerm (PCurrencySymbol :--> PAssetClass :--> PAssetClass :--> PValidator)
mkStakeValidator impl =
plam $ \sstSymbol pstClass gstClass _datum redeemer ctx -> unTermCont $ do
ctxF <- pletFieldsC @'["txInfo", "purpose"] ctx
txInfo <- pletC $ pfromData ctxF.txInfo
txInfoF <-
pletFieldsC
@'[ "inputs"
, "referenceInputs"
, "outputs"
, "mint"
, "validRange"
, "signatories"
, "redeemers"
, "datums"
]
txInfo
--------------------------------------------------------------------------
--------------------------------------------------------------------------
-- Assemble the proposal context.
PSpending stakeInputRef <- pmatchC $ pfromData ctxF.purpose
let AssetClass (propCs, propTn) = proposalSTAssetClass as
let validatedInput =
pfield @"resolved"
#$ passertPJust
# "Malformed script context: validated input not found"
#$ pfindTxInByTxOutRef
# (pfield @"_0" # stakeInputRef)
# txInfoF.inputs
proposalSTClass <-
pletC $
passetClass
# pconstant propCs
# pconstant propTn
stakeValidatorCredential =
pfield @"credential"
#$ pfield @"address" # validatedInput
getProposalDatum <- pletC $
--------------------------------------------------------------------------
-- Returns stake datum if the given UTxO is a stake UTxO.
getStakeDatum :: Term _ (PTxOut :--> PMaybe PStakeDatum) <-
pletC $
plam $
flip pletAll $ \txOutF ->
let isProposalUTxO =
passetClassValueOf
# txOutF.value
# proposalSTClass #== 1
proposalDatum =
pfromData $
pfromOutputDatum @(PAsData PProposalDatum)
# txOutF.datum
# txInfoF.datums
in pif isProposalUTxO (pjust # proposalDatum) pnothing
flip (pletFields @'["value", "datum", "address"]) $ \txOutF ->
pmatch
( pcompareBy # pfromOrd
# (psymbolValueOf # sstSymbol # txOutF.value)
# 1
)
$ \case
-- > 1
PGT -> ptraceError "More than one SST in one UTxO"
-- 1
PEQ ->
let ownerCredential = pfield @"credential" # txOutF.address
let pstMinted =
passetClassValueOf # txInfoF.mint # proposalSTClass #== 1
isOwnedByStakeValidator =
ownerCredential #== stakeValidatorCredential
newProposalContext =
pcon $
PNewProposal $
pfield @"proposalId"
#$ passertPJust # "Proposal output should present"
#$ pfindJust # getProposalDatum # pfromData txInfoF.outputs
datum =
ptrace "Resolve stake datum" $
pfromData $
pfromOutputDatum @(PAsData PStakeDatum)
# txOutF.datum
# txInfoF.datums
in passert
"Should owned by stake validator"
isOwnedByStakeValidator
(pjust # datum)
-- 0
PLT -> pnothing
spendProposalContext =
let getProposalRedeemer = plam $ \ref ->
flip (ptryFrom @PProposalRedeemer) fst $
pto $
passertPJust
# "Malformed script context: propsoal input not found in redeemer map"
#$ plookup
# pcon
( PSpending $
pdcons @_0
# pdata ref
# pdnil
)
# txInfoF.redeemers
--------------------------------------------------------------------------
getContext = plam $
flip pletAll $ \inInfoF ->
pfmap
# plam
( \proposalDatum ->
let id = pfield @"proposalId" # proposalDatum
status = pfield @"status" # proposalDatum
redeemer = getProposalRedeemer # inInfoF.outRef
in pcon $ PSpendProposal id status redeemer
)
#$ getProposalDatum
# pfromData inInfoF.resolved
-- Find all stake inputs.
contexts =
pmapMaybe @PList # getContext # pfromData txInfoF.inputs
in -- Can only handle one proposal at a time.
precList
( \_ h t ->
pif
(pnull # t)
(pjust # h)
(ptraceError "Ambiguous proposal")
)
(const pnothing)
# contexts
stakeInputDatums <-
pletC $
pmapMaybe
# plam ((getStakeDatum #) . (pfield @"resolved" #))
# pfromData txInfoF.inputs
noProposalContext = pcon PNoProposal
--------------------------------------------------------------------------
proposalContext <-
pletC $
-- Assemble the signature context.
firstStakeInputDatumF <-
pletFieldsC @'["owner", "delegatedTo"] $
phead # stakeInputDatums
restOfStakeInputDatums <- pletC $ ptail # stakeInputDatums
authorizedBy <- pletC $ pauthorizedBy # authorizationContext txInfoF
PPair allHaveSameOwner allHaveSameDelegatee <-
pmatchC $
pfoldr
# plam
( \d p -> unTermCont $ do
dF <- pletFieldsC @'["owner", "delegatedTo"] d
pure $
pmatch p $ \(PPair allHaveSameOwner allHaveSameDelegatee) ->
let allHaveSameOwner' =
allHaveSameOwner
#&& dF.owner #== firstStakeInputDatumF.owner
allHaveSameDelegatee' =
allHaveSameDelegatee
#&& dF.delegatedTo #== firstStakeInputDatumF.delegatedTo
in pcon $ PPair allHaveSameOwner' allHaveSameDelegatee'
)
# pcon (PPair (pconstant True) (pconstant True))
# restOfStakeInputDatums
let ownerSignsTransaction =
allHaveSameOwner
#&& authorizedBy # firstStakeInputDatumF.owner
delegateSignsTransaction =
allHaveSameDelegatee
#&& pmaybeData
# pconstant False
# plam ((authorizedBy #) . pfromData)
# pfromData firstStakeInputDatumF.delegatedTo
signedBy =
pif
pstMinted
newProposalContext
(pfromMaybe # noProposalContext # spendProposalContext)
ownerSignsTransaction
(pcon PSignedByOwner)
$ pif
delegateSignsTransaction
(pcon PSignedByDelegate)
$ pcon PUnknownSig
--------------------------------------------------------------------------
sigContext <-
pletC $
pcon $
PSigContext
firstStakeInputDatumF.owner
firstStakeInputDatumF.delegatedTo
signedBy
-- Assemeble the redeemer handler context.
--------------------------------------------------------------------------
mkRedeemerhandlerContext <- pletC $
plam $ \redeemerContext ->
-- Find all stake outputs.
-- First step of validating stake outputs. We make sure that every stake
-- output UTxO carries correct amount of GTs specified by its datum.
--
-- Note that non-GT assets are treated transparently.
stakeOutputDatums <-
pletC $
pmapMaybe
# plam
( \output ->
let validateGT = plam $ \stakeDatum ->
let expected = pfield @"stakedAmount" # stakeDatum
actual =
pvalueDiscrete
# gstClass
# (pfield @"value" # output)
in pif
(expected #== actual)
stakeDatum
(ptraceError "Unmatched GT value")
in pfmap
# validateGT
# (getStakeDatum # output)
)
# pfromData txInfoF.outputs
--------------------------------------------------------------------------
mintedST <- pletC $ psymbolValueOf # sstSymbol # txInfoF.mint
pguardC "No new SST minted" $
foldl1
(#||)
[ ptraceIfTrue "All stakes burnt" $
mintedST #< 0 #&& pnull # stakeOutputDatums
, ptraceIfTrue "Nothing burnt" $
mintedST #== 0
]
--------------------------------------------------------------------------
-- Assemble the proposal context.
getProposalDatum <- pletC $
plam $
flip pletAll $ \txOutF ->
let isProposalUTxO =
passetClassValueOf
# txOutF.value
# pstClass #== 1
proposalDatum =
pfromData $
pfromOutputDatum @(PAsData PProposalDatum)
# txOutF.datum
# txInfoF.datums
in pif isProposalUTxO (pjust # proposalDatum) pnothing
let pstMinted =
passetClassValueOf # txInfoF.mint # pstClass #== 1
newProposalContext =
pcon $
PStakeRedeemerHandlerContext
stakeInputDatums
stakeOutputDatums
redeemerContext
sigContext
proposalContext
txInfo
PNewProposal $
pfield @"proposalId"
#$ passertPJust # "Proposal output should present"
#$ pfindJust # getProposalDatum # pfromData txInfoF.outputs
noMetadataContext <-
pletC $
mkRedeemerhandlerContext
#$ pcon
$ PNoMetadata
spendProposalContext =
let getProposalRedeemer = plam $ \ref ->
flip (ptryFrom @PProposalRedeemer) fst $
pto $
passertPJust
# "Malformed script context: propsoal input not found in redeemer map"
#$ plookup
# pcon
( PSpending $
pdcons @_0
# pdata ref
# pdnil
)
# txInfoF.redeemers
--------------------------------------------------------------------------
getContext = plam $
flip pletAll $ \inInfoF ->
pfmap
# plam
( \proposalDatum ->
let id = pfield @"proposalId" # proposalDatum
status = pfield @"status" # proposalDatum
redeemer = getProposalRedeemer # inInfoF.outRef
in pcon $ PSpendProposal id status redeemer
)
#$ getProposalDatum
# pfromData inInfoF.resolved
-- Call the redeemer handler.
contexts =
pmapMaybe @PList # getContext # pfromData txInfoF.inputs
in -- Can only handle one proposal at a time.
precList
( \_ h t ->
pif
(pnull # t)
(pjust # h)
(ptraceError "Ambiguous proposal")
)
(const pnothing)
# contexts
stakeRedeemer <- fst <$> ptryFromC redeemer
noProposalContext = pcon PNoProposal
pure $
popaque $
pmatch stakeRedeemer $ \case
PDestroy _ -> runStakeRedeemerHandler impl.onDestroy # noMetadataContext
PPermitVote _ -> runStakeRedeemerHandler impl.onPermitVote # noMetadataContext
PRetractVotes _ -> runStakeRedeemerHandler impl.onRetractVote # noMetadataContext
PClearDelegate _ -> runStakeRedeemerHandler impl.onClearDelegate # noMetadataContext
PDelegateTo ((pfield @"pkh" #) -> pkh) ->
runStakeRedeemerHandler impl.onDelegateTo
#$ mkRedeemerhandlerContext
#$ pcon
$ PSetDelegateTo pkh
PDepositWithdraw ((pfield @"delta" #) -> delta) ->
runStakeRedeemerHandler impl.onDepositWithdraw #$ mkRedeemerhandlerContext
#$ pcon
$ PDepositWithdrawDelta delta
proposalContext <-
pletC $
pif
pstMinted
newProposalContext
(pfromMaybe # noProposalContext # spendProposalContext)
--------------------------------------------------------------------------
-- Assemeble the redeemer handler context.
mkRedeemerhandlerContext <- pletC $
plam $ \redeemerContext ->
pcon $
PStakeRedeemerHandlerContext
stakeInputDatums
stakeOutputDatums
redeemerContext
sigContext
proposalContext
txInfo
noMetadataContext <-
pletC $
mkRedeemerhandlerContext
#$ pcon
$ PNoMetadata
--------------------------------------------------------------------------
-- Call the redeemer handler.
stakeRedeemer <- fst <$> ptryFromC redeemer
pure $
popaque $
pmatch stakeRedeemer $ \case
PDestroy _ -> runStakeRedeemerHandler impl.onDestroy # noMetadataContext
PPermitVote _ -> runStakeRedeemerHandler impl.onPermitVote # noMetadataContext
PRetractVotes _ -> runStakeRedeemerHandler impl.onRetractVote # noMetadataContext
PClearDelegate _ -> runStakeRedeemerHandler impl.onClearDelegate # noMetadataContext
PDelegateTo ((pfield @"pkh" #) -> pkh) ->
runStakeRedeemerHandler impl.onDelegateTo
#$ mkRedeemerhandlerContext
#$ pcon
$ PSetDelegateTo pkh
PDepositWithdraw ((pfield @"delta" #) -> delta) ->
runStakeRedeemerHandler impl.onDepositWithdraw #$ mkRedeemerhandlerContext
#$ pcon
$ PDepositWithdrawDelta delta
{- | Validator intended for Stake UTXOs to be locked by.
@ -617,14 +591,16 @@ mkStakeValidator
- The stakes must not be locked.
- Tx must be signed by the owner.
@since 0.1.0
== Arguments
Following arguments should be provided(in this order):
1. stake ST symbol
2. proposal ST assetclass
3. governor ST assetclass
@since 1.0.0
-}
stakeValidator ::
-- | Lazy precompiled scripts.
AgoraScripts ->
-- | See 'Agora.Governor.Governor.gtClassRef'.
Tagged GTTag AssetClass ->
ClosedTerm PValidator
stakeValidator :: ClosedTerm (PCurrencySymbol :--> PAssetClass :--> PAssetClass :--> PValidator)
stakeValidator =
mkStakeValidator $
StakeRedeemerImpl