aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--packages/contracts/src/contracts/current/test/TestLibBytes/TestLibBytes.sol4
-rw-r--r--packages/contracts/src/contracts/current/utils/LibBytes/LibBytes.sol35
-rw-r--r--packages/contracts/test/libraries/lib_bytes.ts26
3 files changed, 50 insertions, 15 deletions
diff --git a/packages/contracts/src/contracts/current/test/TestLibBytes/TestLibBytes.sol b/packages/contracts/src/contracts/current/test/TestLibBytes/TestLibBytes.sol
index 299452c96..60ee3db7f 100644
--- a/packages/contracts/src/contracts/current/test/TestLibBytes/TestLibBytes.sol
+++ b/packages/contracts/src/contracts/current/test/TestLibBytes/TestLibBytes.sol
@@ -53,12 +53,12 @@ contract TestLibBytes {
/// @param lhs First byte array to compare.
/// @param rhs Second byte array to compare.
/// @return True if arrays are the same. False otherwise.
- function publicAreBytesEqual(bytes memory lhs, bytes memory rhs)
+ function publicEquals(bytes memory lhs, bytes memory rhs)
public
pure
returns (bool equal)
{
- equal = lhs.areBytesEqual(rhs);
+ equal = lhs.equals(rhs);
return equal;
}
diff --git a/packages/contracts/src/contracts/current/utils/LibBytes/LibBytes.sol b/packages/contracts/src/contracts/current/utils/LibBytes/LibBytes.sol
index 58ce31c70..2862ee3dd 100644
--- a/packages/contracts/src/contracts/current/utils/LibBytes/LibBytes.sol
+++ b/packages/contracts/src/contracts/current/utils/LibBytes/LibBytes.sol
@@ -258,6 +258,41 @@ library LibBytes {
return result;
}
+ /// @dev Tests equality of two byte arrays.
+ /// @param lhs First byte array to compare.
+ /// @param rhs Second byte array to compare.
+ /// @return True if arrays are the same. False otherwise.
+ function equals(
+ bytes memory lhs,
+ bytes memory rhs
+ )
+ internal
+ pure
+ returns (bool equal)
+ {
+ assembly {
+ // Get the number of words occupied by <lhs>
+ let lenFullWords := div(add(mload(lhs), 0x1F), 0x20)
+
+ // Add 1 to the number of words, to account for the length field
+ lenFullWords := add(lenFullWords, 0x1)
+
+ // Test equality word-by-word.
+ // Terminates early if there is a mismatch.
+ for {let i := 0} lt(i, lenFullWords) {i := add(i, 1)} {
+ let lhsWord := mload(add(lhs, mul(i, 0x20)))
+ let rhsWord := mload(add(rhs, mul(i, 0x20)))
+ equal := eq(lhsWord, rhsWord)
+ if eq(equal, 0) {
+ // Break
+ i := lenFullWords
+ }
+ }
+ }
+
+ return equal;
+ }
+
/// @dev Reads an address from a position in a byte array.
/// @param b Byte array containing an address.
/// @param index Index in byte array of address.
diff --git a/packages/contracts/test/libraries/lib_bytes.ts b/packages/contracts/test/libraries/lib_bytes.ts
index 3afa2bab4..0c8431a6a 100644
--- a/packages/contracts/test/libraries/lib_bytes.ts
+++ b/packages/contracts/test/libraries/lib_bytes.ts
@@ -129,48 +129,48 @@ describe('LibBytes', () => {
});
});
- describe('areBytesEqual', () => {
+ describe('equals', () => {
it('should return true if byte arrays are equal (both arrays < 32 bytes)', async () => {
- const areBytesEqual = await libBytes.publicAreBytesEqual.callAsync(
+ const equals = await libBytes.publicEquals.callAsync(
byteArrayShorterThan32Bytes,
byteArrayShorterThan32Bytes,
);
- return expect(areBytesEqual).to.be.true();
+ return expect(equals).to.be.true();
});
it('should return true if byte arrays are equal (both arrays > 32 bytes)', async () => {
- const areBytesEqual = await libBytes.publicAreBytesEqual.callAsync(
+ const equals = await libBytes.publicEquals.callAsync(
byteArrayLongerThan32Bytes,
byteArrayLongerThan32Bytes,
);
- return expect(areBytesEqual).to.be.true();
+ return expect(equals).to.be.true();
});
it('should return false if byte arrays are not equal (first array < 32 bytes, second array > 32 bytes)', async () => {
- const areBytesEqual = await libBytes.publicAreBytesEqual.callAsync(
+ const equals = await libBytes.publicEquals.callAsync(
byteArrayShorterThan32Bytes,
byteArrayLongerThan32Bytes,
);
- return expect(areBytesEqual).to.be.false();
+ return expect(equals).to.be.false();
});
it('should return false if byte arrays are not equal (first array > 32 bytes, second array < 32 bytes)', async () => {
- const areBytesEqual = await libBytes.publicAreBytesEqual.callAsync(
+ const equals = await libBytes.publicEquals.callAsync(
byteArrayLongerThan32Bytes,
byteArrayShorterThan32Bytes,
);
- return expect(areBytesEqual).to.be.false();
+ return expect(equals).to.be.false();
});
it('should return false if byte arrays are not equal (same length, but a byte in first word differs)', async () => {
- const areBytesEqual = await libBytes.publicAreBytesEqual.callAsync(
+ const equals = await libBytes.publicEquals.callAsync(
byteArrayLongerThan32BytesFirstBytesSwapped,
byteArrayLongerThan32Bytes,
);
- return expect(areBytesEqual).to.be.false();
+ return expect(equals).to.be.false();
});
it('should return false if byte arrays are not equal (same length, but a byte in last word differs)', async () => {
- const areBytesEqual = await libBytes.publicAreBytesEqual.callAsync(
+ const equals = await libBytes.publicEquals.callAsync(
byteArrayLongerThan32BytesLastBytesSwapped,
byteArrayLongerThan32Bytes,
);
- return expect(areBytesEqual).to.be.false();
+ return expect(equals).to.be.false();
});
});