@@ -12,6 +12,8 @@ import BotPlutusInterface.Types (
1212 )
1313import Control.Lens ((&) , (.~) , (<>~) , (^.) )
1414import Data.Default (Default (def ))
15+ import Data.Function (on )
16+ import Data.List (delete , partition )
1517import Data.Map qualified as Map
1618import Data.Set qualified as Set
1719import Data.Text qualified as Text
@@ -33,6 +35,7 @@ import Ledger.Tx (
3335 TxOut (.. ),
3436 TxOutRef (.. ),
3537 )
38+ import Ledger.Value (AssetClass , Value )
3639import Ledger.Value qualified as Value
3740import Plutus.V1.Ledger.Api qualified as Api
3841import PlutusTx qualified
@@ -101,23 +104,33 @@ utxo1, utxo2, utxo3, utxo4, utxo7 :: (TxOutRef, TxOut)
101104utxo1 = (txOutRef1, TxOut addr1 (Ada. lovelaceValueOf 1_100_000 ) Nothing )
102105utxo2 = (txOutRef2, TxOut addr1 (Ada. lovelaceValueOf 1_000_000 ) Nothing )
103106utxo3 = (txOutRef3, TxOut addr1 (Ada. lovelaceValueOf 900_000 ) Nothing )
104- utxo4 = (txOutRef4, TxOut addr1 (Ada. lovelaceValueOf 800_000 <> Value. singleton " 11223344 " " Token " 200 ) Nothing )
107+ utxo4 = (txOutRef4, TxOut addr1 (Ada. lovelaceValueOf 800_000 <> Value. assetClassValue tokenAsset 200 ) Nothing )
105108-- utxo5 = (txOutRef5, TxOut addr3 (Ada.lovelaceValueOf 900_000) (Just $ Ledger.DatumHash ""))
106109-- utxo6 = (txOutRef6, TxOut addr3 (Value.singleton "11223344" "Token" 200) Nothing)
107110utxo7 = (txOutRef2, TxOut addr1 (Ada. lovelaceValueOf 5_000_000 ) Nothing )
108111
109112scrValue :: Value. Value
110- scrValue = Value. singleton " 11223344 " " Token " 200 <> Ada. lovelaceValueOf 500_000
113+ scrValue = Value. assetClassValue tokenAsset 200 <> Ada. lovelaceValueOf 500_000
111114
112115scrValue' :: Value. Value
113- scrValue' = Value. singleton " 11223344 " " Token " 100 <> Ada. lovelaceValueOf 500_000
116+ scrValue' = Value. assetClassValue tokenAsset 120 <> Ada. lovelaceValueOf 500_000
114117
115118scrDatum :: Ledger. Datum
116119scrDatum = Ledger. Datum $ Api. toBuiltinData (23 :: Integer )
117120
118121scrDatumHash :: Ledger. DatumHash
119122scrDatumHash = Ledger. datumHash scrDatum
120123
124+ acValueOf :: AssetClass -> Value -> Integer
125+ acValueOf = flip Value. assetClassValueOf
126+
127+ -- | Get the amount of lovelace in a `Value`.
128+ lovelaceInValue :: Value -> Integer
129+ lovelaceInValue = acValueOf (Value. assetClass Api. adaSymbol Api. adaToken)
130+
131+ tokenAsset :: Value. AssetClass
132+ tokenAsset = Value. assetClass " 11223344" " Token"
133+
121134addUtxosForFees :: Assertion
122135addUtxosForFees = do
123136 let txout = TxOut addr2 (Ada. lovelaceValueOf 1_000_000 ) Nothing
@@ -229,12 +242,17 @@ dontAddChangeToDatum = do
229242 (Right (Right trx)) -> do
230243 let scrTxOut'' = scrTxOut' & Ledger. ciTxOutValue <>~ Ada. lovelaceValueOf 500
231244 scrTxOutExpected = Ledger. toTxOut scrTxOut''
245+ isScrUtxo :: TxOut -> Bool
246+ isScrUtxo utxo = txOutAddress utxo == txOutAddress scrTxOutExpected
247+ (balScrUtxos, balOtherUtxos) = partition isScrUtxo (txOutputs trx)
232248 assertBool
233249 ( " Expected UTxO not in output Tx."
234250 <> " \n Expected UTxO: "
235251 <> show scrTxOutExpected
236- <> " \n New UTxOs: "
237- <> show (txOutputs trx)
252+ <> " \n Balanced Script UTxOs: "
253+ <> show balScrUtxos
254+ <> " \n Other Balanced UTxOs: "
255+ <> show balOtherUtxos
238256 <> " \n Unbalanced UTxOs: "
239257 <> show (txOutputs (unbalancedTx ^. OffChain. tx))
240258 )
@@ -265,10 +283,10 @@ dontAddChangeToDatum2 = do
265283 -- - 200 tokens
266284 -- Output UTxO :
267285 -- - 0.5 ADA
268- -- - 100 tokens
286+ -- - 120 tokens
269287 -- Change:
270288 -- - 1.5 ADA (400 Lovelace to fees)
271- -- - 100 tokens
289+ -- - 80 tokens
272290
273291 scrLkups =
274292 Constraints. unspentOutputs (Map. fromList [(txOutRef6, scrTxOut')])
@@ -293,13 +311,54 @@ dontAddChangeToDatum2 = do
293311 (Right (Right trx)) -> do
294312 let scrTxOut'' = scrTxOut' & Ledger. ciTxOutValue .~ scrValue'
295313 scrTxOutExpected = Ledger. toTxOut scrTxOut''
314+ isScrUtxo :: TxOut -> Bool
315+ isScrUtxo utxo = txOutAddress utxo == txOutAddress scrTxOutExpected
316+ (balScrUtxos, balOtherUtxos) = partition isScrUtxo (txOutputs trx)
317+ -- Check that the expected script UTxO
318+ -- is in the output.
296319 assertBool
297320 ( " Expected UTxO not in output Tx."
298321 <> " \n Expected UTxO: "
299322 <> show scrTxOutExpected
300- <> " \n New UTxOs: "
301- <> show (txOutputs trx)
323+ <> " \n Balanced Script UTxOs: "
324+ <> show balScrUtxos
325+ <> " \n Other Balanced UTxOs: "
326+ <> show balOtherUtxos
302327 <> " \n Unbalanced UTxOs: "
303328 <> show (txOutputs (unbalancedTx ^. OffChain. tx))
304329 )
305330 (scrTxOutExpected `elem` txOutputs trx)
331+ -- Check that the output has the remaining change
332+ let trxFee = txFee trx
333+ adaChange' :: Integer
334+ adaChange' = ((-) `on` (lovelaceInValue . txOutValue)) scrTxOut scrTxOutExpected
335+ adaChange :: Integer
336+ adaChange = adaChange' - lovelaceInValue trxFee
337+ tokChange :: Integer
338+ tokChange = ((-) `on` (acValueOf tokenAsset . txOutValue)) scrTxOut scrTxOutExpected
339+ remainingTxOuts :: [TxOut ]
340+ remainingTxOuts = delete scrTxOutExpected (txOutputs trx)
341+ remainingValue :: Value. Value
342+ remainingValue = foldMap txOutValue remainingTxOuts
343+ -- Check for ADA change
344+ assertBool
345+ ( " Other UTxOs do not contain expected ADA change."
346+ <> " \n Expected Amount : "
347+ <> show adaChange
348+ <> " Lovelace"
349+ <> " \n Actual Amount : "
350+ <> show (lovelaceInValue remainingValue)
351+ <> " Lovelace"
352+ )
353+ (adaChange == lovelaceInValue remainingValue)
354+ -- Check for Token change
355+ assertBool
356+ ( " Other UTxOs do not contain expected Token change."
357+ <> " \n Expected Amount : "
358+ <> show tokChange
359+ <> " tokens"
360+ <> " \n Actual Amount : "
361+ <> show (acValueOf tokenAsset remainingValue)
362+ <> " tokens"
363+ )
364+ (tokChange == acValueOf tokenAsset remainingValue)
0 commit comments