ethereum: Check that bytes32 fits into 20 bytes before truncating (#1457)

This commit is contained in:
Csongor Kiss 2022-08-23 20:41:03 +02:00 committed by GitHub
parent a8cc328fd0
commit fd540c91b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 2 deletions

View File

@ -472,6 +472,17 @@ contract Bridge is BridgeGovernance, ReentrancyGuard {
_completeTransfer(encodedVm, true);
}
/*
* @dev Truncate a 32 byte array to a 20 byte address.
* Reverts if the array contains non-0 bytes in the first 12 bytes.
*
* @param bytes32 bytes The 32 byte array to be converted.
*/
function _truncateAddress(bytes32 b) internal pure returns (address) {
require(bytes12(b) == 0, "invalid EVM address");
return address(uint160(uint256(b)));
}
// Execute a Transfer message
function _completeTransfer(bytes memory encodedVm, bool unwrapWETH) internal returns (bytes memory) {
(IWormhole.VM memory vm, bool valid, string memory reason) = wormhole().parseAndVerifyVM(encodedVm);
@ -482,7 +493,7 @@ contract Bridge is BridgeGovernance, ReentrancyGuard {
BridgeStructs.Transfer memory transfer = _parseTransferCommon(vm.payload);
// payload 3 must be redeemed by the designated proxy contract
address transferRecipient = address(uint160(uint256(transfer.to)));
address transferRecipient = _truncateAddress(transfer.to);
if (transfer.payloadID == 3) {
require(msg.sender == transferRecipient, "invalid sender");
}
@ -494,7 +505,7 @@ contract Bridge is BridgeGovernance, ReentrancyGuard {
IERC20 transferToken;
if (transfer.tokenChain == chainId()) {
transferToken = IERC20(address(uint160(uint256(transfer.tokenAddress))));
transferToken = IERC20(_truncateAddress(transfer.tokenAddress));
// track outstanding token amounts
bridgedIn(address(transferToken), transfer.amount);

View File

@ -0,0 +1,16 @@
// SPDX-License-Identifier: Apache 2
pragma solidity ^0.8.0;
import "../contracts/bridge/Bridge.sol";
import "forge-std/Test.sol";
contract TestBridge is Bridge, Test {
function testTruncate(bytes32 b) public {
if (bytes12(b) != 0) {
vm.expectRevert( "invalid EVM address");
}
bytes32 converted = bytes32(uint256(uint160(bytes20(_truncateAddress(b)))));
require(converted == b, "truncate does not roundrip");
}
}