Skip to content

Commit 7fe8d9b

Browse files
committed
feat(standing_bid): implement ConcludeAuction sub-validator
1 parent b6cb780 commit 7fe8d9b

File tree

4 files changed

+112
-6
lines changed

4 files changed

+112
-6
lines changed

hydra-auction-onchain.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ library
111111
HydraAuctionOnchain.Types.BidTerms
112112
HydraAuctionOnchain.Types.Error
113113
HydraAuctionOnchain.Types.StandingBidState
114+
HydraAuctionOnchain.Validators.AuctionEscrow
114115
HydraAuctionOnchain.Validators.AuctionMetadata
115116
HydraAuctionOnchain.Validators.StandingBid
116117

src/HydraAuctionOnchain/Helpers.hs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,22 @@
33
module HydraAuctionOnchain.Helpers
44
( pdecodeInlineDatum
55
, pfindUnique
6+
, pfindUniqueInputWithToken
67
, pfindUniqueOutputWithAddress
78
, pintervalFiniteClosedOpen
89
, pserialise
910
, putxoAddress
1011
) where
1112

13+
import Plutarch.Api.V1.Value (pvalueOf)
1214
import Plutarch.Api.V2
1315
( PAddress
16+
, PCurrencySymbol
1417
, PExtended (PFinite)
1518
, PInterval (PInterval)
1619
, PLowerBound (PLowerBound)
1720
, POutputDatum (POutputDatum)
21+
, PTokenName
1822
, PTxInInfo
1923
, PTxInfo
2024
, PTxOut
@@ -40,6 +44,24 @@ pfindUnique = phoistAcyclic $
4044
plam $ \predicate list ->
4145
pfromSingleton #$ pfilter # predicate # list
4246

47+
pfindUniqueInputWithToken
48+
:: Term
49+
s
50+
( PCurrencySymbol
51+
:--> PTokenName
52+
:--> PTxInfo
53+
:--> PMaybe PTxInInfo
54+
)
55+
pfindUniqueInputWithToken = phoistAcyclic $
56+
plam $ \cs tn txInfo ->
57+
pfindUnique
58+
# plam
59+
( \utxo ->
60+
pvalueOf # (pfield @"value" #$ pfield @"resolved" # utxo) # cs # tn #== 1
61+
)
62+
#$ pfield @"inputs"
63+
# txInfo
64+
4365
pfindUniqueOutputWithAddress :: Term s (PAddress :--> PTxInfo :--> PMaybe PTxOut)
4466
pfindUniqueOutputWithAddress = phoistAcyclic $
4567
plam $ \addr txInfo ->
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
module HydraAuctionOnchain.Validators.AuctionEscrow
2+
( pisConcluding
3+
) where
4+
5+
--------------------------------------------------------------------------------
6+
-- Redeemers
7+
--------------------------------------------------------------------------------
8+
9+
data PAuctionEscrowRedeemer (s :: S)
10+
= StartBiddingRedeemer (Term s (PDataRecord '[]))
11+
| BidderBuysRedeemer (Term s (PDataRecord '[]))
12+
| SellerReclaimsRedeemer (Term s (PDataRecord '[]))
13+
| CleanupAuctionRedeemer (Term s (PDataRecord '[]))
14+
deriving stock (Generic)
15+
deriving anyclass (PlutusType, PIsData, PShow, PEq)
16+
17+
instance DerivePlutusType PAuctionEscrowRedeemer where
18+
type DPTStrat _ = PlutusTypeData
19+
20+
instance PTryFrom PData (PAsData PAuctionEscrowRedeemer)
21+
22+
pisConcluding :: Term s (PAuctionEscrowRedeemer :--> PBool)
23+
pisConcluding = phoistAcyclic $
24+
plam $ \redeemer -> pmatch redeemer $ \case
25+
BidderBuysRedeemer _ -> pcon PTrue
26+
SellerReclaimsRedeemer _ -> pcon PTrue
27+
_ -> pcon PFalse

src/HydraAuctionOnchain/Validators/StandingBid.hs

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,30 @@ module HydraAuctionOnchain.Validators.StandingBid
44

55
import HydraAuctionOnchain.Helpers
66
( pdecodeInlineDatum
7+
, pfindUniqueInputWithToken
78
, pfindUniqueOutputWithAddress
89
, putxoAddress
910
)
10-
import HydraAuctionOnchain.MintingPolicies.Auction (standingBidTokenName)
11+
import HydraAuctionOnchain.MintingPolicies.Auction
12+
( auctionEscrowTokenName
13+
, standingBidTokenName
14+
)
1115
import HydraAuctionOnchain.Types.AuctionTerms (PAuctionTerms, pbiddingPeriod)
1216
import HydraAuctionOnchain.Types.Error (ToErrorCode (toErrorCode), err, perrMaybe)
1317
import HydraAuctionOnchain.Types.StandingBidState (PStandingBidState, pvalidateNewBid)
18+
import HydraAuctionOnchain.Validators.AuctionEscrow (pisConcluding)
1419
import Plutarch.Api.V1.Value (pvalueOf)
15-
import Plutarch.Api.V2 (PCurrencySymbol, PScriptContext, PTxInInfo, PTxInfo, PTxOut)
20+
import Plutarch.Api.V2
21+
( PCurrencySymbol
22+
, PScriptContext
23+
, PScriptPurpose (PSpending)
24+
, PTxInInfo
25+
, PTxInfo
26+
, PTxOut
27+
)
1628
import Plutarch.Extra.Interval (pcontains)
17-
import Plutarch.Extra.ScriptContext (ptryOwnInput, ptxSignedBy)
29+
import Plutarch.Extra.Maybe (pmaybe)
30+
import Plutarch.Extra.ScriptContext (ptryFromRedeemer, ptryOwnInput, ptxSignedBy)
1831
import Plutarch.Monadic qualified as P
1932

2033
--------------------------------------------------------------------------------
@@ -97,6 +110,24 @@ instance ToErrorCode PStandingBid'MoveToHydra'Error where
97110
StandingBid'MoveToHydra'Error'IncorrectValidityInterval ->
98111
pconstant "StandingBid_MoveToHydra_02"
99112

113+
-- ConcludeAuction -------------------------------------------------------------
114+
data PStandingBid'ConcludeAuction'Error (s :: S)
115+
= StandingBid'ConcludeAuction'Error'MissingAuctionEscrowInput
116+
| StandingBid'ConcludeAuction'Error'InvalidAuctionEscrowRedeemer
117+
deriving stock (Generic)
118+
deriving anyclass (PlutusType)
119+
120+
instance DerivePlutusType PStandingBid'ConcludeAuction'Error where
121+
type DPTStrat _ = PlutusTypeScott
122+
123+
instance ToErrorCode PStandingBid'ConcludeAuction'Error where
124+
toErrorCode = phoistAcyclic $
125+
plam $ \err -> pmatch err $ \case
126+
StandingBid'ConcludeAuction'Error'MissingAuctionEscrowInput ->
127+
pconstant "StandingBid_ConcludeAuction_01"
128+
StandingBid'ConcludeAuction'Error'InvalidAuctionEscrowRedeemer ->
129+
pconstant "StandingBid_ConcludeAuction_02"
130+
100131
--------------------------------------------------------------------------------
101132
-- Validator
102133
--------------------------------------------------------------------------------
@@ -133,7 +164,7 @@ standingBidValidator = phoistAcyclic $
133164
MoveToHydraRedeemer _ ->
134165
pcheckMoveToHydra # txInfo # auctionTerms
135166
ConcludeAuctionRedeemer _ ->
136-
pcheckConcludeAuction
167+
pcheckConcludeAuction # txInfo # auctionCs
137168

138169
--------------------------------------------------------------------------------
139170
-- NewBid
@@ -213,8 +244,33 @@ pcheckMoveToHydra = phoistAcyclic $
213244
-- ConcludeAuction
214245
--------------------------------------------------------------------------------
215246

216-
pcheckConcludeAuction :: Term s PUnit
217-
pcheckConcludeAuction = undefined
247+
pcheckConcludeAuction :: Term s (PTxInfo :--> PCurrencySymbol :--> PUnit)
248+
pcheckConcludeAuction = phoistAcyclic $
249+
plam $ \txInfo auctionCs -> P.do
250+
-- (StandingBid_ConcludeAuction_01)
251+
-- There is an input that contains the auction escrow token.
252+
auctionEscrowUtxo <-
253+
plet $
254+
perrMaybe
255+
# pcon StandingBid'ConcludeAuction'Error'MissingAuctionEscrowInput
256+
# (pfindUniqueInputWithToken # auctionCs # auctionEscrowTokenName # txInfo)
257+
258+
-- (StandingBid_ConcludeAuction_02)
259+
-- The auction escrow input is being spent with the `BidderBuys` or
260+
-- `SellerReclaims` redeemer. Implicitly, this means that the auction is
261+
-- concluding with either the winning bidder buying the auction lot or the
262+
-- seller reclaiming it.
263+
redeemers <- plet $ pfield @"redeemers" # txInfo
264+
auctionEscrowOref <- plet $ pfield @"outRef" # auctionEscrowUtxo
265+
spendsAuctionEscrow <- plet $ pcon $ PSpending $ pdcons @"_0" # auctionEscrowOref # pdnil
266+
auctionEscrowRedeemer <- plet $ ptryFromRedeemer # spendsAuctionEscrow # redeemers
267+
err StandingBid'ConcludeAuction'Error'InvalidAuctionEscrowRedeemer $
268+
pmaybe
269+
# pcon PFalse
270+
# plam (\redeemer -> pisConcluding # pfromData redeemer)
271+
# auctionEscrowRedeemer
272+
273+
pcon PUnit
218274

219275
--------------------------------------------------------------------------------
220276
-- Helpers

0 commit comments

Comments
 (0)