Skip to content

Commit

Permalink
fix hexToStr in Ibc library
Browse files Browse the repository at this point in the history
  • Loading branch information
RnkSngh committed May 7, 2024
1 parent 3161ac7 commit f808e61
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 20 deletions.
1 change: 1 addition & 0 deletions contracts/libs/IbcErrors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ library IBCErrors {
error invalidAddress();
error invalidPortPrefix();
error notEnoughGas();
error invalidCharacter();

// packet sequence related errors.
error invalidPacketSequence();
Expand Down
54 changes: 34 additions & 20 deletions contracts/libs/IbcUtils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,32 +35,46 @@ library IbcUtils {
* hexStr is case-insensitive.
*/
function hexStrToAddress(string memory hexStr) public pure returns (address addr) {
bytes memory hexBytes = bytes(hexStr);
if (bytes(hexStr).length != 40) {
revert IBCErrors.invalidHexStringLength();
revert IBCErrors.invalidHexStringLength(); // Addresses must always be 20 bytes long; equal to 40 nibbles
}

bytes memory strBytes = bytes(hexStr);
bytes memory addrBytes = new bytes(20);

for (uint256 i = 0; i < 20; i++) {
uint8 high = uint8(strBytes[i * 2]);
uint8 low = uint8(strBytes[1 + i * 2]);
// Convert to lowercase if the character is in uppercase
if (high >= 65 && high <= 90) {
high += 32;
}
if (low >= 65 && low <= 90) {
low += 32;
uint256 total = 0;
uint256 base = 1;
uint256 i = 40;
while (i > 0) {
i--;
uint256 digit;
// Convert ASCII to integer value
if (uint8(hexBytes[i]) >= 48 && uint8(hexBytes[i]) <= 57) {
/**
* This triggers if hexBytes[i] is equal to '0' to '9'
* '0' - '9' are 48-57 in ascii, and we want to map this into 0-9, so we subtract 48
*/
digit = uint160(uint8(hexBytes[i]) - 48);
} else if (uint8(hexBytes[i]) >= 65 && uint8(hexBytes[i]) <= 70) {
/**
* This triggers if hexBytes[i] is equal to 'A' to 'F'
* 'A' - 'F' are 65-70 in ascii, and we want to map this into 0xa-0xf (equal to 10-15), so we
* sutract 55
*/
digit = uint160(uint8(hexBytes[i]) - 55);
} else if (uint8(hexBytes[i]) >= 97 && uint8(hexBytes[i]) <= 102) {
/**
* This triggers if hexBytes[i] is equal to 'a' to 'f'
* 'a' to 'f' are 97-102 in ascii, and we want to amp this into 0xa-0xf (equal to 10-15), so we
* sutract 87
*/
digit = uint160(uint8(hexBytes[i]) - 87);
} else {
revert IBCErrors.invalidCharacter();
}
uint8 digit = (high - (high >= 97 ? 87 : 48)) * 16 + (low - (low >= 97 ? 87 : 48));
addrBytes[i] = bytes1(digit);
}

assembly {
addr := mload(add(addrBytes, 20))
total += digit * base;
base *= 16;
}

return addr;
addr = address(uint160(total));
}

function toUniversalPacketBytes(UniversalPacket memory data) internal pure returns (bytes memory packetBytes) {
Expand Down
22 changes: 22 additions & 0 deletions test/Ibc.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,26 @@ contract IbcTest is Test {
"daf;lkdsajflkasjdv;lkjzdljga;lkgfjda;iocjvz;lkjval;dsjkf;alkdj;zlkjv;lkjaeg;ijafd;lkjzvc,mnb.kahgd;ajkfaj;dgoij;zlckjv;lzkjv;kaldfjg;alkjgf;lkzvjcx;lkvja;lkjg;aslgjdz;adf;kasjg;lkjwaea;lkjg;io1j;4kjrda;lkfjaleot8ywp89yz;dvhlsdkj"
);
}

function test_InvalidHexStr_To_Address() public {
string memory validString = "2B5AD5c4795c026514f8317c7a215E218DcCD6cF"; // Can't start with g
assertEq(IbcUtils.hexStrToAddress(validString), vm.addr(2));

string memory invalidHexStr1 = "123"; // Too Short
vm.expectRevert(abi.encodeWithSelector(IBCErrors.invalidHexStringLength.selector));
IbcUtils.hexStrToAddress(invalidHexStr1);

string memory invalidHexStr2 = "2B5AD5c4795c026514f8317c7a215E218DcCD6cFa"; // Too long
vm.expectRevert(abi.encodeWithSelector(IBCErrors.invalidHexStringLength.selector));
IbcUtils.hexStrToAddress(invalidHexStr2);

string memory invalidHexStr3 = "2G5AD5c4795c026514f8317c7a215E218DcCD6cF"; // Can't have G
vm.expectRevert(abi.encodeWithSelector(IBCErrors.invalidCharacter.selector));
IbcUtils.hexStrToAddress(invalidHexStr3);
}

function test_To_From_addr_hexStr(address addr) public {
bytes memory hexStr = IbcUtils.toHexStr(addr);
assertEq(addr, IbcUtils.hexStrToAddress(string(hexStr)));
}
}

0 comments on commit f808e61

Please sign in to comment.