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
8 changes: 4 additions & 4 deletions script/smoke/chain.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,8 +331,8 @@ def _revert_bytes(exc: ContractLogicError) -> bytes | None:
def expect_abi_decode_failed(self, desc: str, fn, frm: ChecksumAddress) -> None:
"""Simulate `fn` via eth_call; assert Rust precompile AbiDecodeFailed revert shape.

Dispatch decode failures encode as `function_selector || utf8_error`, not a typed
custom error such as InvalidVariant().
Dispatch decode failures encode as a bare `function_selector` (no message; the error
string was dropped), not a typed custom error such as InvalidVariant().
"""
fn_selector = bytes(HexBytes(fn.selector))
try:
Expand Down Expand Up @@ -361,7 +361,7 @@ def _assert_abi_decode_revert(
if raw is None:
self._diagnose(f"expected ABI decode failure: {desc}", repro_fn, repro_overrides, repro_call)
die(f"expected ABI decode failure for {desc} but revert had no data")
if len(raw) <= 4:
if len(raw) < 4:
self._diagnose(f"expected ABI decode failure: {desc}", repro_fn, repro_overrides, repro_call)
die(f"expected ABI decode failure for {desc} but revert was only {len(raw)} byte(s): 0x{raw.hex()}")
if raw[:4] != fn_selector:
Expand All @@ -382,7 +382,7 @@ def expect_raw_abi_decode_failed(
value: int = 0,
frm: ChecksumAddress | None = None,
) -> None:
"""Assert hand-built calldata reverts with AbiDecodeFailed (selector || utf8)."""
"""Assert hand-built calldata reverts with AbiDecodeFailed (bare selector, no message)."""
if len(data) < 4:
die(f"expected ABI decode failure for {desc} but calldata is shorter than 4 bytes")
fn_selector = data[:4]
Expand Down
22 changes: 2 additions & 20 deletions script/smoke/journeys/stablecoin_lifecycle.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,9 @@
from __future__ import annotations

from .. import config
from ..abis import STABLECOIN_ABI
from ..chain import Chain, log, step
from ..codec import StablecoinCreateParams, init_call

# `burnBlocked` is a deprecated precompile selector that base-std #186 removed from the IB20
# interface, so it is absent from STABLECOIN_ABI. The selector still dispatches on the precompile
# (retained for back-compat), so bind it via an explicit fragment to keep exercising the legacy
# burn-based freeze-and-seize path. The transfer-based seize surface is covered by the `seize` journey.
_BURN_BLOCKED_FRAGMENT = {
"type": "function",
"name": "burnBlocked",
"stateMutability": "nonpayable",
"inputs": [{"name": "from", "type": "address"}, {"name": "amount", "type": "uint256"}],
"outputs": [],
}


def _burn_blocked_at(c: Chain, tok):
"""A token binding including the deprecated `burnBlocked` selector (absent from STABLECOIN_ABI)."""
return c.w3.eth.contract(address=tok.address, abi=[*STABLECOIN_ABI, _BURN_BLOCKED_FRAGMENT])


def _setup(c: Chain):
salt = c.cfg.salt_for("stablecoin")
Expand Down Expand Up @@ -73,7 +55,7 @@ def _journey(c: Chain, tok) -> None:
c.assert_eq(c.policy.functions.isAuthorized(pid, c.ALICE).call(), False, "alice blocked")

step(5, "seize: burnBlocked(alice, 400); Transfer then BurnedBlocked")
receipt = c.send(_burn_blocked_at(c, tok).functions.burnBlocked(c.ALICE, config.amt(400, 6)), c.deployer)
receipt = c.send(tok.functions.burnBlocked(c.ALICE, config.amt(400, 6)), c.deployer)
c.assert_eq(tok.functions.balanceOf(c.ALICE).call(), config.amt(600, 6), "alice balance after seize")
c.assert_eq(tok.functions.totalSupply().call(), config.amt(1100, 6), "total supply after seize")
c.assert_log_order(
Expand All @@ -86,7 +68,7 @@ def _journey(c: Chain, tok) -> None:

def _edges(c: Chain, tok) -> None:
step(6, "seize an unblocked account -> AccountNotBlocked")
c.expect_revert("AccountNotBlocked", _burn_blocked_at(c, tok).functions.burnBlocked(c.BOB, 1), c.DEPLOYER)
c.expect_revert("AccountNotBlocked", tok.functions.burnBlocked(c.BOB, 1), c.DEPLOYER)

step(7, "role gate: user2 mint -> AccessControlUnauthorizedAccount")
c.expect_revert("AccessControlUnauthorizedAccount", tok.functions.mint(c.ALICE, 1), c.USER2)
Expand Down
Loading