1
+ {-# LANGUAGE UndecidableInstances #-}
2
+
3
+ module ErgoDex.PContracts.LqMining.Simple.PDeposit where
4
+
5
+ import qualified GHC.Generics as GHC
6
+
7
+ import Plutarch
8
+ import Plutarch.Api.V2 (POutputDatum (POutputDatum ), PPubKeyHash , PDatum (PDatum ), PTokenName (.. ), PCurrencySymbol (.. ))
9
+ import Plutarch.Api.V2.Contexts (PScriptContext , PScriptPurpose (PSpending ))
10
+ import Plutarch.DataRepr
11
+ import Plutarch.Lift
12
+ import Plutarch.Prelude
13
+ import Plutarch.Extra.TermCont
14
+
15
+ import PExtra.API (PAssetClass , assetClassValueOf , ptryFromData , assetClass , tletUnwrap )
16
+ import PExtra.Monadic (tlet , tletField , tmatch )
17
+
18
+ import ErgoDex.PContracts.PApi (containsSignature , getRewardValueByPkh' )
19
+
20
+ import qualified ErgoDex.Contracts.Proxy.LqMining.Simple.Deposit as D
21
+ import qualified ErgoDex.PContracts.LqMining.Simple.PStakingBundle as SB
22
+ import qualified ErgoDex.PContracts.LqMining.Simple.PLMPool as LMPool
23
+
24
+ newtype DepositConfig (s :: S )
25
+ = DepositConfig
26
+ ( Term
27
+ s
28
+ ( PDataRecord
29
+ '[ " expectedNumEpochs" ':= PInteger
30
+ , " bundleKeyCS" ':= PCurrencySymbol
31
+ , " redeemerPkh" ':= PPubKeyHash
32
+ , " vlqAC" ':= PAssetClass
33
+ , " tmpAC" ':= PAssetClass
34
+ ]
35
+ )
36
+ )
37
+ deriving stock (GHC.Generic )
38
+ deriving
39
+ (PIsData , PDataFields , PlutusType )
40
+
41
+ instance DerivePlutusType DepositConfig where type DPTStrat _ = PlutusTypeData
42
+
43
+ instance PUnsafeLiftDecl DepositConfig where type PLifted DepositConfig = D. DepositConfig
44
+ deriving via (DerivePConstantViaData D. DepositConfig DepositConfig ) instance (PConstantDecl D. DepositConfig )
45
+
46
+ newtype DepositRedeemer (s :: S )
47
+ = DepositRedeemer
48
+ ( Term
49
+ s
50
+ ( PDataRecord
51
+ '[ " poolInIdx" ':= PInteger
52
+ , " depositInIdx" ':= PInteger
53
+ , " redeemerOutIdx" ':= PInteger
54
+ , " bundleOutIdx" ':= PInteger
55
+ ]
56
+ )
57
+ )
58
+ deriving stock (GHC.Generic )
59
+ deriving
60
+ (PIsData , PDataFields , PlutusType )
61
+
62
+ instance DerivePlutusType DepositRedeemer where type DPTStrat _ = PlutusTypeData
63
+
64
+ instance PUnsafeLiftDecl DepositRedeemer where type PLifted DepositRedeemer = D. DepositRedeemer
65
+ deriving via (DerivePConstantViaData D. DepositRedeemer DepositRedeemer ) instance (PConstantDecl D. DepositRedeemer )
66
+
67
+ depositValidatorT :: ClosedTerm (DepositConfig :--> DepositRedeemer :--> PScriptContext :--> PBool )
68
+ depositValidatorT = plam $ \ conf' redeemer' ctx' -> unTermCont $ do
69
+ ctx <- pletFieldsC @ '[" txInfo" , " purpose" ] ctx'
70
+ conf <- pletFieldsC @ '[" expectedNumEpochs" , " bundleKeyCS" , " redeemerPkh" , " vlqAC" , " tmpAC" ] conf'
71
+ redeemer <- pletFieldsC @ '[" poolInIdx" , " depositInIdx" , " redeemerOutIdx" , " bundleOutIdx" ] redeemer'
72
+
73
+ txInfo <- pletFieldsC @ '[" inputs" , " outputs" , " signatories" ] $ getField @ " txInfo" ctx
74
+ inputs <- tletUnwrap $ getField @ " inputs" txInfo
75
+ outputs <- tletUnwrap $ getField @ " outputs" txInfo
76
+ let
77
+ poolInIx = getField @ " poolInIdx" redeemer
78
+ depositInIdx = getField @ " depositInIdx" redeemer
79
+ redeemerOutIdx = getField @ " redeemerOutIdx" redeemer
80
+ bundleOutIdx = getField @ " bundleOutIdx" redeemer
81
+
82
+ expectedNumEpochs = getField @ " expectedNumEpochs" conf
83
+
84
+ redeemerPkh = getField @ " redeemerPkh" conf
85
+ vlqAC = getField @ " vlqAC" conf
86
+ bundleKeyCS = getField @ " bundleKeyCS" conf
87
+ tmpAC = getField @ " tmpAC" conf
88
+
89
+ sigs = pfromData $ getField @ " signatories" txInfo
90
+
91
+ signedByRedeemPkh = containsSignature # sigs # redeemerPkh
92
+
93
+ selfIn' <- tlet $ pelemAt # depositInIdx # inputs
94
+ selfIn <- pletFieldsC @ '[" outRef" , " resolved" ] selfIn'
95
+ selfValue <-
96
+ let self = getField @ " resolved" selfIn
97
+ in tletField @ " value" self
98
+
99
+ PSpending selfRef' <- tmatch (pfromData $ getField @ " purpose" ctx)
100
+
101
+ let
102
+ selfIdentity =
103
+ let selfRef = pfromData $ pfield @ " _0" # selfRef'
104
+ selfInRef = pfromData $ getField @ " outRef" selfIn
105
+ in selfRef #== selfInRef
106
+
107
+ poolIn' <- tlet $ pelemAt # poolInIx # inputs
108
+ poolOutRef <- tletUnwrap $ pfield @ " outRef" # poolIn'
109
+ let
110
+ poolId = pfield @ " id" # poolOutRef
111
+ lqTnBytes = pcon $ PTokenName $ pfield @ " _0" # poolId
112
+
113
+ redeemerOut' <- tlet $ pelemAt # redeemerOutIdx # outputs
114
+ let
115
+ redeemerValue = getRewardValueByPkh' # redeemerOut' # redeemerPkh
116
+
117
+ lqAc = assetClass # bundleKeyCS # lqTnBytes
118
+
119
+ redeemerLqValue = assetClassValueOf # redeemerValue # lqAc
120
+ correctLqValue = redeemerLqValue #== LMPool. lqQty
121
+
122
+ bundleOut' <- tlet $ pelemAt # bundleOutIdx # outputs
123
+ bundleOut <- pletFieldsC @ '[" value" , " datum" ] bundleOut'
124
+ let
125
+ bundleValue = getField @ " value" bundleOut
126
+ datumOD' = getField @ " datum" bundleOut
127
+
128
+ POutputDatum bundleOD' <- pmatchC datumOD'
129
+
130
+ bundleOD <- tletField @ " outputDatum" bundleOD'
131
+
132
+ PDatum bundleDatum'' <- pmatchC bundleOD
133
+
134
+ bundleDatum' <- tlet $ ptryFromData @ (SB. StakingBundleConfig ) $ bundleDatum''
135
+ bundleDatum <- pletFieldsC @ '[" bundleLQAC" , " redeemerPkh" ] bundleDatum'
136
+ let
137
+ bundleLQAC = getField @ " bundleLQAC" bundleDatum
138
+
139
+ redeemerPkhBundle = getField @ " redeemerPkh" bundleDatum
140
+
141
+ vlqIn = assetClassValueOf # selfValue # vlqAC
142
+ vlqOut = assetClassValueOf # bundleValue # vlqAC
143
+ tmpOut = assetClassValueOf # bundleValue # tmpAC
144
+
145
+ validVLQQty = vlqIn #== vlqOut
146
+ validTMPQty = (vlqIn * expectedNumEpochs) #== tmpOut
147
+
148
+ validBundleRedeemer = redeemerPkh #== redeemerPkhBundle
149
+
150
+ validBundleAC = bundleLQAC #== lqAc
151
+
152
+ pure $ signedByRedeemPkh #|| (selfIdentity #&& validVLQQty #&& validTMPQty #&& validBundleRedeemer #&& correctLqValue #&& validBundleAC)
0 commit comments