diff --git a/CHANGELOG.md b/CHANGELOG.md index b856be6bb5d..007688e535c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * `TimelockController`: Migrate `_call` to `_execute` and allow inheritance and overriding similar to `Governor`. ([#3317](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3317)) * `CrossChainEnabledPolygonChild`: replace the `require` statement with the custom error `NotCrossChainCall`. ([#3380](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3380)) * `ERC20FlashMint`: Add customizable flash fee receiver. ([#3327](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3327)) + * `Strings`: add a new overloaded function `toHexString` that converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. ([#3403](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3403)) ## 4.6.0 (2022-04-26) diff --git a/contracts/mocks/StringsMock.sol b/contracts/mocks/StringsMock.sol index f257734e76f..b8622680bab 100644 --- a/contracts/mocks/StringsMock.sol +++ b/contracts/mocks/StringsMock.sol @@ -16,4 +16,8 @@ contract StringsMock { function fromUint256HexFixed(uint256 value, uint256 length) public pure returns (string memory) { return Strings.toHexString(value, length); } + + function fromAddressHexFixed(address addr) public pure returns (string memory) { + return Strings.toHexString(addr); + } } diff --git a/contracts/utils/Strings.sol b/contracts/utils/Strings.sol index d38bbe8267e..5b3e12d135c 100644 --- a/contracts/utils/Strings.sol +++ b/contracts/utils/Strings.sol @@ -8,6 +8,7 @@ pragma solidity ^0.8.0; */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; + uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. @@ -64,4 +65,11 @@ library Strings { require(value == 0, "Strings: hex length insufficient"); return string(buffer); } + + /** + * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. + */ + function toHexString(address addr) internal pure returns (string memory) { + return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); + } } diff --git a/test/utils/Strings.test.js b/test/utils/Strings.test.js index 5128ce577dc..8dda829ea96 100644 --- a/test/utils/Strings.test.js +++ b/test/utils/Strings.test.js @@ -56,4 +56,16 @@ contract('Strings', function (accounts) { .to.equal(web3.utils.toHex(constants.MAX_UINT256)); }); }); + + describe('from address - fixed hex format', function () { + it('converts a random address', async function () { + const addr = '0xa9036907dccae6a1e0033479b12e837e5cf5a02f'; + expect(await this.strings.fromAddressHexFixed(addr)).to.equal(addr); + }); + + it('converts an address with leading zeros', async function () { + const addr = '0x0000e0ca771e21bd00057f54a68c30d400000000'; + expect(await this.strings.fromAddressHexFixed(addr)).to.equal(addr); + }); + }); });