Since Solidity 0.8, arithmetic reverts on overflow and underflow. Turning that off takes an explicit unchecked { ... } block. Rust goes the other way. A debug build panics, but build with --release and the default is two's complement wrapping. You only get checks in release if the Cargo profile sets overflow-checks = true. In C signed overflow is undefined behavior, and the compiler may simply delete a check written after the fact.
For code that moves balances I think Solidity has the right default. A wrapped result gets stored as a wrong balance. A revert rolls back the whole transaction. A failure beats a wrong number that stays forever.
Both have the same hole, though. In Solidity an explicit conversion truncates even in checked mode, so uint128(x) does not revert. Rust's as truncates silently too. A checked addition followed by a narrowing cast is unchecked in practice.
So the rule I've settled on. No unchecked in amount arithmetic. Checks on in the Rust release profile. Amount casts only through try_from. Has anyone kept overflow-checks on in release builds? I'm curious whether the cost is noticeable.