Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/erc7730/convert/calldata/v1/tlv.py
Original file line number Diff line number Diff line change
Expand Up @@ -473,8 +473,8 @@ def tlv_param_unit(obj: CalldataDescriptorParamUnitV1) -> bytes:
out += tlv(CalldataDescriptorParamUnitTag.VALUE, tlv_value(obj.value))
out += tlv(CalldataDescriptorParamUnitTag.BASE, obj.base)

if (decimals := obj.decimals) is not None:
out += tlv(CalldataDescriptorParamUnitTag.DECIMALS, decimals.to_bytes(1))
# always emit DECIMALS (defaulting to 0): app-ethereum >= 1.22.4 rejects PARAM_UNIT structs without it
out += tlv(CalldataDescriptorParamUnitTag.DECIMALS, (obj.decimals or 0).to_bytes(1))

if (prefix := obj.prefix) is not None:
out += tlv(CalldataDescriptorParamUnitTag.PREFIX, prefix.to_bytes(1))
Expand Down
19 changes: 18 additions & 1 deletion tests/v2/convert/calldata/test_convert_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@
from erc7730.convert.calldata.convert_erc7730_v2_input_to_calldata import (
erc7730_v2_descriptor_to_calldata_descriptors,
)
from erc7730.convert.calldata.v1.tlv import CalldataDescriptorFieldTag, tlv_field
from erc7730.convert.calldata.v1.tlv import (
CalldataDescriptorFieldTag,
CalldataDescriptorParamUnitTag,
tlv_field,
tlv_param_unit,
)
from erc7730.model.calldata.v1.instruction import (
CalldataDescriptorFieldVisibilityV1,
CalldataDescriptorInstructionFieldV1,
Expand Down Expand Up @@ -204,6 +209,18 @@ def test_convert_unit_params() -> None:
assert field.param.prefix is False


@pytest.mark.parametrize(("decimals", "expected"), [pytest.param(None, 0, id="unset"), pytest.param(4, 4, id="set")])
def test_convert_unit_always_serializes_decimals(decimals: int | None, expected: int) -> None:
params: dict[str, Any] = {"base": "s"} if decimals is None else {"base": "s", "decimals": decimals}
field = convert_field(
"setDuration(uint256 duration)", {"path": "duration", "label": "Duration", "format": "unit", "params": params}
)

assert isinstance(field.param, CalldataDescriptorParamUnitV1)
values = dict(parse_tlv(tlv_param_unit(field.param)))
assert values[CalldataDescriptorParamUnitTag.DECIMALS] == bytes([expected])


def test_convert_token_ticker_has_no_native_currencies() -> None:
field = convert_field(
"getTokenTicker(address token)",
Expand Down
Loading