subtractValueQuantities pass token map as reference
jmagan opened this issue · 1 comments
Summary
Hi!,
The substractTokenMap method pass the asset token map as reference. In the first line of the method, it assings position array 0 to the result constant:
export const subtractTokenMaps = (assets: (TokenMap | undefined)[]): TokenMap | undefined => {
if (assets.length <= 0 || !isNotNil(assets[0])) return undefined;
const result: TokenMap = assets[0];
const rest: TokenMap[] = assets.slice(1).filter(isNotNil);
for (const assetTotals of rest) {
for (const [assetId, assetQuantity] of assetTotals.entries()) {
const total = result.get(assetId) ?? 0n;
const diff = total - assetQuantity;
diff === 0n ? result.delete(assetId) : result.set(assetId, diff);
}
}
if (result.size === 0) {
return undefined;
}
return result;
};
That produces changes in the first position of the value array passed to subtractValueQuantities, as I show in the example. I would suggest to create a copy of the object instead of pass it as reference.
Thanks.
Steps to reproduce the bug
- This script shows the test case:
import { Cardano } from '@cardano-sdk/core';
const cardanoAsset: Cardano.AssetId = Cardano.AssetId('01234567890123456789012345678901234567890123456789012345678901234567890123456789');
// First value with 10 ADA and 10 tokens
const tokenMap1: Cardano.TokenMap = new Map([[cardanoAsset, 10n]]);
const value1: Cardano.Value = { coins: 10000000n, assets: tokenMap1 };
console.log(`Value 1 before subtraction: ${Number(value1.coins) / (10 ** 6)} ADA and ${value1.assets!.get(cardanoAsset)!.toString()} Token`);
// Second value with 5 ADA and 5 tokens
const tokenMap2: Cardano.TokenMap = new Map([[cardanoAsset, 5n]]);
const value2: Cardano.Value = { coins: 5000000n, assets: tokenMap2 };
// Substract value 2 to value 1
const result = Cardano.util.subtractValueQuantities([value1, value2]);
console.log(`Value 1 after subtraction: ${Number(value1.coins) / (10 ** 6)} ADA and ${value1.assets!.get(cardanoAsset)!.toString()} Token`);
console.log(`Result value: ${Number(result.coins) / (10 ** 6)} ADA and ${result.assets!.get(cardanoAsset)!.toString()} Token`);
Actual Result
The script out put is:
Value 1 before subtraction: 10 ADA and 10 Token
Value 1 after subtraction: 10 ADA and 5 Token
Result value: 5 ADA and 5 Token
Expected Result
My expected result is:
Value 1 before subtraction: 10 ADA and 10 Token
Value 1 after subtraction: 10 ADA and 10 Token
Result value: 5 ADA and 5 Token
SDK version
0.5.0
Environment type
- Node.js
- Browser
- Browser Extension
- Other
Environment details
v14.20.0
Thanks for raising this issue @jmagan. We're open for contributions, either as a complete fix or just a failing test in this suite, so feel free to submit a PR to be recognised for your work here 🙂