Add Strings.toString for signed integers (#3773)
Co-authored-by: Hadrien Croubois <hadrien.croubois@gmail.com> Co-authored-by: Gbolahan <89295500+GbolahanAnon@users.noreply.github.com> Co-authored-by: Francisco Giordano <frangio.1@gmail.com>
This commit is contained in:
@ -8,6 +8,7 @@
|
|||||||
* `Initializable`: optimize `_disableInitializers` by using `!=` instead of `<`. ([#3787](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3787))
|
* `Initializable`: optimize `_disableInitializers` by using `!=` instead of `<`. ([#3787](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3787))
|
||||||
* `Math`: optimize `log256` rounding check. ([#3745](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3745))
|
* `Math`: optimize `log256` rounding check. ([#3745](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3745))
|
||||||
* `Strings`: add `equal` method. ([#3774](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3774))
|
* `Strings`: add `equal` method. ([#3774](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3774))
|
||||||
|
* `Strings`: add `toString` method for signed integers. ([#3773](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3773))
|
||||||
|
|
||||||
### Deprecations
|
### Deprecations
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,10 @@ contract StringsMock {
|
|||||||
return Strings.toString(value);
|
return Strings.toString(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toString(int256 value) public pure returns (string memory) {
|
||||||
|
return Strings.toString(value);
|
||||||
|
}
|
||||||
|
|
||||||
function toHexString(uint256 value) public pure returns (string memory) {
|
function toHexString(uint256 value) public pure returns (string memory) {
|
||||||
return Strings.toHexString(value);
|
return Strings.toHexString(value);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
pragma solidity ^0.8.0;
|
pragma solidity ^0.8.0;
|
||||||
|
|
||||||
import "./math/Math.sol";
|
import "./math/Math.sol";
|
||||||
|
import "./math/SignedMath.sol";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev String operations.
|
* @dev String operations.
|
||||||
@ -37,6 +38,13 @@ library Strings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Converts a `int256` to its ASCII `string` decimal representation.
|
||||||
|
*/
|
||||||
|
function toString(int256 value) internal pure returns (string memory) {
|
||||||
|
return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value))));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
|
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -10,7 +10,7 @@ contract('Strings', function (accounts) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('toString', function () {
|
describe('toString', function () {
|
||||||
for (const [ key, value ] of Object.entries([
|
const values = [
|
||||||
'0',
|
'0',
|
||||||
'7',
|
'7',
|
||||||
'10',
|
'10',
|
||||||
@ -29,13 +29,43 @@ contract('Strings', function (accounts) {
|
|||||||
'12345678901234567890123456789012345678901234567890',
|
'12345678901234567890123456789012345678901234567890',
|
||||||
'123456789012345678901234567890123456789012345678901234567890',
|
'123456789012345678901234567890123456789012345678901234567890',
|
||||||
'1234567890123456789012345678901234567890123456789012345678901234567890',
|
'1234567890123456789012345678901234567890123456789012345678901234567890',
|
||||||
].reduce((acc, value) => Object.assign(acc, { [value]: new BN(value) }), {
|
];
|
||||||
MAX_UINT256: constants.MAX_UINT256.toString(),
|
|
||||||
}))) {
|
describe('uint256', function () {
|
||||||
it(`converts ${key}`, async function () {
|
it('converts MAX_UINT256', async function () {
|
||||||
|
const value = constants.MAX_UINT256;
|
||||||
expect(await this.strings.methods['toString(uint256)'](value)).to.equal(value.toString(10));
|
expect(await this.strings.methods['toString(uint256)'](value)).to.equal(value.toString(10));
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
for (const value of values) {
|
||||||
|
it(`converts ${value}`, async function () {
|
||||||
|
expect(await this.strings.methods['toString(uint256)'](value)).to.equal(value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('int256', function () {
|
||||||
|
it('converts MAX_INT256', async function () {
|
||||||
|
const value = constants.MAX_INT256;
|
||||||
|
expect(await this.strings.methods['toString(int256)'](value)).to.equal(value.toString(10));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('converts MIN_INT256', async function () {
|
||||||
|
const value = constants.MIN_INT256;
|
||||||
|
expect(await this.strings.methods['toString(int256)'](value)).to.equal(value.toString(10));
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const value of values) {
|
||||||
|
it(`convert ${value}`, async function () {
|
||||||
|
expect(await this.strings.methods['toString(int256)'](value)).to.equal(value);
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`convert negative ${value}`, async function () {
|
||||||
|
const negated = new BN(value).neg();
|
||||||
|
expect(await this.strings.methods['toString(int256)'](negated)).to.equal(negated.toString(10));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('toHexString', function () {
|
describe('toHexString', function () {
|
||||||
|
|||||||
Reference in New Issue
Block a user