@@ -2264,3 +2264,65 @@ def test_burning_all_assets_under_single_policy(chain_context):
22642264
22652265 assert AssetName (b"AssetName3" ) not in multi_asset .get (policy_id_1 , {})
22662266 assert AssetName (b"AseetName4" ) not in multi_asset .get (policy_id_1 , {})
2267+
2268+
2269+ def test_collateral_no_duplicates (chain_context ):
2270+ """
2271+ Test that a UTxO explicitly added as input is not reused for collateral.
2272+ """
2273+ # Setup: Define sender and a Plutus script for minting (requires collateral)
2274+ sender = "addr_test1vrm9x2zsux7va6w892g38tvchnzahvcd9tykqf3ygnmwtaqyfg52x"
2275+ sender_address = Address .from_primitive (sender )
2276+ plutus_v2_script = PlutusV2Script (b"dummy mint script collateral reuse test" )
2277+ policy_id = plutus_script_hash (plutus_v2_script )
2278+ redeemer = Redeemer (PlutusData (), ExecutionUnits (1000000 , 1000000 ))
2279+
2280+ input_utxo = UTxO (
2281+ TransactionInput (TransactionId .from_primitive ("a" * 64 ), 0 ),
2282+ TransactionOutput (sender_address , Value (coin = 2_800_000 )),
2283+ )
2284+ collateral_utxo = UTxO (
2285+ TransactionInput (TransactionId .from_primitive ("b" * 64 ), 1 ),
2286+ TransactionOutput (sender_address , Value (coin = 3_000_000 )),
2287+ )
2288+
2289+ with patch .object (chain_context , "utxos" ) as mock_utxos :
2290+ mock_utxos .return_value = [input_utxo , collateral_utxo ]
2291+
2292+ builder = TransactionBuilder (chain_context )
2293+
2294+ builder .add_input (input_utxo )
2295+ builder .add_input_address (sender_address )
2296+
2297+ mint_amount = 1
2298+ builder .mint = MultiAsset .from_primitive (
2299+ {policy_id .payload : {b"TestCollateralToken" : mint_amount }}
2300+ )
2301+ builder .add_minting_script (plutus_v2_script , redeemer )
2302+
2303+ output_value = Value (coin = 1_000_000 ) # Send some ADA back
2304+ builder .add_output (TransactionOutput (sender_address , output_value ))
2305+
2306+ tx_body = builder .build (change_address = sender_address )
2307+
2308+ assert input_utxo .input in tx_body .inputs
2309+
2310+ assert tx_body .collateral is not None
2311+ assert len (tx_body .collateral ) > 0 , "Collateral should have been selected"
2312+
2313+ assert (
2314+ collateral_utxo .input in tx_body .collateral
2315+ ), "The designated collateral UTxO was not selected"
2316+
2317+ assert (
2318+ input_utxo .input in tx_body .collateral
2319+ ), "The explicit input UTxO should be reused as collateral"
2320+
2321+ total_collateral_input = (
2322+ collateral_utxo .output .amount + input_utxo .output .amount
2323+ )
2324+
2325+ assert (
2326+ total_collateral_input
2327+ == Value (tx_body .total_collateral ) + tx_body .collateral_return .amount
2328+ ), "The total collateral input amount should match the sum of the selected UTxOs"
0 commit comments