Skip to content

MultiAsset: use structural equality in getAsset/hasAsset/subtract and fix Value.geq #390

Description

@solidsnakedev

Summary

MultiAsset.getAsset, hasAsset, getAssetsByPolicy, and subtract look up keys with raw Map.get, which compares PolicyId/AssetName by reference. Keys decoded from CBOR are fresh instances, so lookups miss structurally equal keys. addAsset and Assets.quantityOf already do this correctly with Equal.equals. As a result MultiAsset.subtract returns the minuend unchanged, getAsset/hasAsset/getAssetsByPolicy return undefined/false/empty on decoded data, and Value.geq (which only checks that subtract did not throw) returns true even when funds are insufficient.

Affected

packages/evolution/src/MultiAsset.ts getAsset (L293), hasAsset (L307), getAssetsByPolicy (L330), subtract (L556)
packages/evolution/src/Value.ts geq (L226-233), subtract
correct pattern to copy: MultiAsset.addAsset (L246/L258), Assets.quantityOf

Fix

Make getAsset, hasAsset, getAssetsByPolicy, and MultiAsset.subtract use Equal.equals loops over the map entries, matching addAsset. Rewrite Value.geq to compare per asset quantities directly rather than inferring sufficiency from subtract not throwing.

Regression test

Use freshly constructed (reference distinct) keys for have and want.

  • given: have = singleton(pid, an, 5), want = singleton(pid, an, 100)
  • before fix: Value.geq(have, want) === true; MultiAsset.subtract(a, a) returns a unchanged; getAsset(singleton(pid, an, n), pid, an) === undefined; getAssetsByPolicy(singleton(pid, an, n), pid) === []
  • after fix: Value.geq(have, want) === false; subtract(a, a) is empty; getAsset(...) === n; getAssetsByPolicy(...) lists the asset

Must FAIL on main today and PASS after the fix.

Reference

Report 4, Report 14

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingexternal-reviewFrom external review batch

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions