Skip to content
Open
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
40 changes: 30 additions & 10 deletions src/libs/TypeConverter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ pragma solidity >=0.8.20 <0.9.0;
/// @author M0 Labs
/// @notice Utilities for converting between different data types.
library TypeConverter {
/// @notice Thrown when a uint256 value exceeds the max uint16 value.
error Uint16Overflow();
/// @notice Thrown when a uint256 value exceeds the max uint32 value.
error Uint32Overflow();
/// @notice Thrown when a uint256 value exceeds the max uint64 value.
error Uint64Overflow();
/// @notice Thrown when a uint256 value exceeds the max uint128 value.
Expand All @@ -13,6 +17,22 @@ library TypeConverter {
/// @notice Thrown when a bytes32 value doesn't represent a valid Ethereum address.
error InvalidAddress(bytes32 value);

/// @notice Converts a uint256 to uint16, reverting if the value overflows.
/// @param value The uint256 value to convert.
/// @return The uint16 representation of the value.
function toUint16(uint256 value) internal pure returns (uint16) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add unit tests for these new functions.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't notice it before but these functions are similar to the ones we have in UintMath.

function safe16(uint256 n) internal pure returns (uint16) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

if (value > type(uint16).max) revert Uint16Overflow();
return uint16(value);
}

/// @notice Converts a uint256 to uint32, reverting if the value overflows.
/// @param value The uint256 value to convert.
/// @return The uint32 representation of the value.
function toUint32(uint256 value) internal pure returns (uint32) {
if (value > type(uint32).max) revert Uint32Overflow();
return uint32(value);
}

/// @notice Converts a uint256 to uint64, reverting if the value overflows.
/// @param value The uint256 value to convert.
/// @return The uint64 representation of the value.
Expand All @@ -31,27 +51,27 @@ library TypeConverter {

/// @notice Convert an Ethereum address to bytes32.
/// @dev Pads the 20-byte address to 32 bytes by converting to uint160, then uint256, then bytes32.
/// @param addressValue The address to convert.
/// @param value The address to convert.
/// @return The bytes32 representation of the address.
function toBytes32(address addressValue) internal pure returns (bytes32) {
return bytes32(uint256(uint160(addressValue)));
function toBytes32(address value) internal pure returns (bytes32) {
return bytes32(uint256(uint160(value)));
}

/// @notice Convert bytes32 to an Ethereum address.
/// @dev Truncates the 32-byte value to 20 bytes by converting to uint256, then uint160, then address.
/// @param bytes32Value The bytes32 value to convert.
/// @param value The bytes32 value to convert.
/// @return The address representation of the bytes32 value.
function toAddress(bytes32 bytes32Value) internal pure returns (address) {
if (!isValidAddress(bytes32Value)) revert InvalidAddress(bytes32Value);
return address(uint160(uint256(bytes32Value)));
function toAddress(bytes32 value) internal pure returns (address) {
if (!isValidAddress(value)) revert InvalidAddress(value);
return address(uint160(uint256(value)));
}

/// @notice Check if a bytes32 value represents a valid Ethereum address.
/// @dev An Ethereum address must have the top 12 bytes as zero.
/// @param bytes32Value The bytes32 value to check.
/// @param value The bytes32 value to check.
/// @return True if the bytes32 value can be safely converted to an Ethereum address.
function isValidAddress(bytes32 bytes32Value) internal pure returns (bool) {
function isValidAddress(bytes32 value) internal pure returns (bool) {
// The top 12 bytes must be zero for a valid Ethereum address
return uint256(bytes32Value) >> 160 == 0;
return uint256(value) >> 160 == 0;
}
}