ethereum: Check that bytes32 fits into 20 bytes before truncating (#1457)
This commit is contained in:
parent
a8cc328fd0
commit
fd540c91b4
|
@ -472,6 +472,17 @@ contract Bridge is BridgeGovernance, ReentrancyGuard {
|
||||||
_completeTransfer(encodedVm, true);
|
_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
|
// Execute a Transfer message
|
||||||
function _completeTransfer(bytes memory encodedVm, bool unwrapWETH) internal returns (bytes memory) {
|
function _completeTransfer(bytes memory encodedVm, bool unwrapWETH) internal returns (bytes memory) {
|
||||||
(IWormhole.VM memory vm, bool valid, string memory reason) = wormhole().parseAndVerifyVM(encodedVm);
|
(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);
|
BridgeStructs.Transfer memory transfer = _parseTransferCommon(vm.payload);
|
||||||
|
|
||||||
// payload 3 must be redeemed by the designated proxy contract
|
// 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) {
|
if (transfer.payloadID == 3) {
|
||||||
require(msg.sender == transferRecipient, "invalid sender");
|
require(msg.sender == transferRecipient, "invalid sender");
|
||||||
}
|
}
|
||||||
|
@ -494,7 +505,7 @@ contract Bridge is BridgeGovernance, ReentrancyGuard {
|
||||||
|
|
||||||
IERC20 transferToken;
|
IERC20 transferToken;
|
||||||
if (transfer.tokenChain == chainId()) {
|
if (transfer.tokenChain == chainId()) {
|
||||||
transferToken = IERC20(address(uint160(uint256(transfer.tokenAddress))));
|
transferToken = IERC20(_truncateAddress(transfer.tokenAddress));
|
||||||
|
|
||||||
// track outstanding token amounts
|
// track outstanding token amounts
|
||||||
bridgedIn(address(transferToken), transfer.amount);
|
bridgedIn(address(transferToken), transfer.amount);
|
||||||
|
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue