Skip to content

Commit 6df20aa

Browse files
Added second test for UTxO change.
This test shows that if an input UTxO has more ADA or Tokens than needed, and is being sent (with a datum) to a script address, the excess value won't go with it.
1 parent cb16ad7 commit 6df20aa

File tree

1 file changed

+80
-4
lines changed

1 file changed

+80
-4
lines changed

test/Spec/BotPlutusInterface/Balance.hs

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ tests =
6060
[ testCase "Add utxos to cover fees" addUtxosForFees
6161
, testCase "Add utxos to cover native tokens" addUtxosForNativeTokens
6262
, testCase "Add utxos to cover change min utxo" addUtxosForChange
63-
, testCase "Don't add change to UTxOs with datums" dontAddChangeToDatum
63+
, testCase "Don't add change to UTxOs with datums (1)" dontAddChangeToDatum
64+
, testCase "Don't add change to UTxOs with datums (2)" dontAddChangeToDatum2
6465
]
6566

6667
validator :: Scripts.Validator
@@ -108,6 +109,9 @@ utxo7 = (txOutRef2, TxOut addr1 (Ada.lovelaceValueOf 5_000_000) Nothing)
108109
scrValue :: Value.Value
109110
scrValue = Value.singleton "11223344" "Token" 200 <> Ada.lovelaceValueOf 500_000
110111

112+
scrValue' :: Value.Value
113+
scrValue' = Value.singleton "11223344" "Token" 100 <> Ada.lovelaceValueOf 500_000
114+
111115
scrDatum :: Ledger.Datum
112116
scrDatum = Ledger.Datum $ Api.toBuiltinData (23 :: Integer)
113117

@@ -185,6 +189,25 @@ dontAddChangeToDatum = do
185189
-- contractEnv' :: ContractEnvironment ()
186190
contractEnv' = def {cePABConfig = pabConf}
187191

192+
-- Input UTxOs:
193+
-- UTxO 1:
194+
-- - From: User
195+
-- - Amt : 1.001 ADA
196+
-- UTxO 2:
197+
-- - From: Script
198+
-- - Amt : 0.5 ADA + 200 Tokens
199+
--
200+
-- Output UTxOs:
201+
-- UTxO 1:
202+
-- - To : User
203+
-- - Amt: 1 ADA
204+
-- UTxO 2:
205+
-- - To : Script
206+
-- - Amt: 1.0005 Ada + 200 Token
207+
--
208+
-- Fees : 400 Lovelace
209+
-- Change : 100 Lovelace
210+
188211
scrLkups =
189212
Constraints.unspentOutputs (Map.fromList [(txOutRef6, scrTxOut'), (txOutRef7, usrTxOut')])
190213
<> Constraints.ownPaymentPubKeyHash paymentPkh3
@@ -208,9 +231,62 @@ dontAddChangeToDatum = do
208231
let scrTxOut'' = scrTxOut' & Ledger.ciTxOutValue <>~ Ada.lovelaceValueOf 500
209232
scrTxOutNew = Ledger.toTxOut scrTxOut''
210233
assertBool
211-
( "Original UTxO not in output Tx."
212-
<> "\nOriginal UTxO: "
213-
<> show scrTxOut
234+
( "Expected UTxO not in output Tx."
235+
<> "\nExpected UTxO: "
236+
<> show scrTxOutNew
237+
<> "\nNew UTxOs: "
238+
<> show (txOutputs trx)
239+
<> "\nUnbalanced UTxOs: "
240+
<> show (txOutputs (unbalancedTx ^. OffChain.tx))
241+
)
242+
(scrTxOutNew `elem` txOutputs trx)
243+
244+
-- Like the first one, but
245+
-- only has inputs from the script.
246+
dontAddChangeToDatum2 :: Assertion
247+
dontAddChangeToDatum2 = do
248+
let scrTxOut' =
249+
ScriptChainIndexTxOut
250+
valAddr
251+
(Right validator) -- (valHash, Just validator)
252+
(Right scrDatum) -- (scrDatumHash, Just scrDatum)
253+
(scrValue <> Ada.lovelaceValueOf 1_500_000)
254+
scrTxOut = Ledger.toTxOut scrTxOut'
255+
-- initState :: MockContractState ()
256+
initState =
257+
def & utxos .~ [(txOutRef6, scrTxOut)]
258+
& contractEnv .~ contractEnv'
259+
pabConf :: PABConfig
260+
pabConf = def {pcOwnPubKeyHash = pkh3}
261+
-- contractEnv' :: ContractEnvironment ()
262+
contractEnv' = def {cePABConfig = pabConf}
263+
264+
scrLkups =
265+
Constraints.unspentOutputs (Map.fromList [(txOutRef6, scrTxOut')])
266+
<> Constraints.ownPaymentPubKeyHash paymentPkh3
267+
txConsts =
268+
-- Pay the same datum to the script, but with LESS ada
269+
-- and fewer tokens. This is to ensure that the excess
270+
-- ADA and tokens are moved into their own UTxO(s),
271+
-- (The extra ada is used to cover fees etc...)
272+
Constraints.mustPayToOtherScript valHash scrDatum scrValue'
273+
<> Constraints.mustSpendScriptOutput txOutRef6 Ledger.unitRedeemer
274+
eunbalancedTx = Constraints.mkTx @Void scrLkups txConsts
275+
276+
case eunbalancedTx of
277+
Left mkTxErr -> assertFailure ("MkTx Error: " <> show mkTxErr)
278+
Right unbalancedTx -> do
279+
let (eRslt, _finalState) = runPABEffectPure initState (balanceTxIO @() @'[PABEffect ()] pabConf pkh3 unbalancedTx)
280+
case eRslt of
281+
(Left txt) -> assertFailure ("PAB effect error: " <> Text.unpack txt)
282+
(Right (Left txt)) -> assertFailure $ "Balancing error: " <> Text.unpack txt -- <> "\n(Tx: " <> show unbalancedTx <> ")"
283+
(Right (Right trx)) -> do
284+
let scrTxOut'' = scrTxOut' & Ledger.ciTxOutValue .~ scrValue'
285+
scrTxOutNew = Ledger.toTxOut scrTxOut''
286+
assertBool
287+
( "Expected UTxO not in output Tx."
288+
<> "\nExpected UTxO: "
289+
<> show scrTxOutNew
214290
<> "\nNew UTxOs: "
215291
<> show (txOutputs trx)
216292
<> "\nUnbalanced UTxOs: "

0 commit comments

Comments
 (0)