Skip to content

Commit

Permalink
Merge pull request #20 from immutable/smr-1914-data-length-32
Browse files Browse the repository at this point in the history
[SMR-1914] data length must be greater than 32
  • Loading branch information
Benjimmutable authored Nov 6, 2023
2 parents b6c05a8 + 2759edd commit de91564
Show file tree
Hide file tree
Showing 8 changed files with 22 additions and 17 deletions.
9 changes: 5 additions & 4 deletions src/child/ChildERC20Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -109,20 +109,21 @@ contract ChildERC20Bridge is
if (!Strings.equal(messageSourceChain, rootChain)) {
revert InvalidSourceChain();
}

if (!Strings.equal(sourceAddress, rootERC20BridgeAdaptor)) {
revert InvalidSourceAddress();
}
if (data.length == 0) {
revert InvalidData();
if (data.length <= 32) {
// Data must always be greater than 32.
// 32 bytes for the signature, and at least some information for the payload
revert InvalidData("Data too short");
}

if (bytes32(data[:32]) == MAP_TOKEN_SIG) {
_mapToken(data);
} else if (bytes32(data[:32]) == DEPOSIT_SIG) {
_deposit(data[32:]);
} else {
revert InvalidData();
revert InvalidData("Unsupported action signature");
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/child/IChildERC20Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ interface IChildERC20BridgeErrors {
/// @notice Error when a message is given to the bridge from an address not the designated bridge adaptor.
error NotBridgeAdaptor();
/// @notice Error when the message's payload is not valid.
error InvalidData();
error InvalidData(string reason);
/// @notice Error when the message's source chain is not valid.
error InvalidSourceChain();
/// @notice Error when the source chain's message sender is not a recognised address.
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/root/IRootERC20Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ interface IRootERC20BridgeErrors {
/// @notice Error when the given child chain bridge adaptor is invalid.
error InvalidChildERC20BridgeAdaptor();
/// @notice Error when a message received has invalid data.
error InvalidData();
error InvalidData(string reason);
/// @notice Error when a message received has invalid source address.
error InvalidSourceAddress();
/// @notice Error when a message received has invalid source chain.
Expand Down
8 changes: 5 additions & 3 deletions src/root/RootERC20Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -164,14 +164,16 @@ contract RootERC20Bridge is
if (!Strings.equal(sourceAddress, childBridgeAdaptor)) {
revert InvalidSourceAddress();
}
if (data.length == 0) {
revert InvalidData();
if (data.length <= 32) {
// Data must always be greater than 32.
// 32 bytes for the signature, and at least some information for the payload
revert InvalidData("Data too short");
}

if (bytes32(data[:32]) == WITHDRAW_SIG) {
_withdraw(data[32:]);
} else {
revert InvalidData();
revert InvalidData("Unsupported action signature");
}
}

Expand Down
4 changes: 2 additions & 2 deletions test/integration/child/ChildAxelarBridge.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ contract ChildERC20BridgeIntegrationTest is Test, IChildERC20BridgeEvents, IChil
bytes32 commandId = bytes32("testCommandId");
bytes memory payload = abi.encode("invalid payload");

vm.expectRevert(InvalidData.selector);
vm.expectRevert(abi.encodeWithSelector(InvalidData.selector, "Unsupported action signature"));
childAxelarBridgeAdaptor.execute(commandId, ROOT_CHAIN_NAME, ROOT_ADAPTOR_ADDRESS, payload);
}

Expand All @@ -109,7 +109,7 @@ contract ChildERC20BridgeIntegrationTest is Test, IChildERC20BridgeEvents, IChil
bytes32 commandId = bytes32("testCommandId");
bytes memory payload = "";

vm.expectRevert(InvalidData.selector);
vm.expectRevert(abi.encodeWithSelector(InvalidData.selector, "Data too short"));
childAxelarBridgeAdaptor.execute(commandId, ROOT_CHAIN_NAME, ROOT_ADAPTOR_ADDRESS, payload);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ contract RootERC20BridgeWithdrawIntegrationTest is
bytes32 commandId = bytes32("testCommandId");
string memory sourceAddress = rootBridge.childBridgeAdaptor();

vm.expectRevert(InvalidData.selector);
vm.expectRevert(abi.encodeWithSelector(InvalidData.selector, "Data too short"));
axelarAdaptor.execute(commandId, CHILD_CHAIN_NAME, sourceAddress, data);
}

Expand All @@ -97,7 +97,7 @@ contract RootERC20BridgeWithdrawIntegrationTest is
bytes32 commandId = bytes32("testCommandId");
string memory sourceAddress = rootBridge.childBridgeAdaptor();

vm.expectRevert(InvalidData.selector);
vm.expectRevert(abi.encodeWithSelector(InvalidData.selector, "Unsupported action signature"));
axelarAdaptor.execute(commandId, CHILD_CHAIN_NAME, sourceAddress, data);
}

Expand Down
4 changes: 2 additions & 2 deletions test/unit/child/ChildERC20Bridge.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -168,15 +168,15 @@ contract ChildERC20BridgeUnitTest is Test, IChildERC20BridgeEvents, IChildERC20B

function test_RevertIf_onMessageReceiveCalledWithDataLengthZero() public {
bytes memory data = "";
vm.expectRevert(InvalidData.selector);
vm.expectRevert(abi.encodeWithSelector(InvalidData.selector, "Data too short"));
childBridge.onMessageReceive(ROOT_CHAIN_NAME, ROOT_BRIDGE_ADAPTOR, data);
}

function test_RevertIf_onMessageReceiveCalledWithDataInvalid() public {
bytes memory data =
abi.encode("FAKEDATA", address(rootToken), rootToken.name(), rootToken.symbol(), rootToken.decimals());

vm.expectRevert(InvalidData.selector);
vm.expectRevert(abi.encodeWithSelector(InvalidData.selector, "Unsupported action signature"));
childBridge.onMessageReceive(ROOT_CHAIN_NAME, ROOT_BRIDGE_ADAPTOR, data);
}

Expand Down
6 changes: 4 additions & 2 deletions test/unit/root/withdrawals/RootERC20BridgeWithdraw.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,16 @@ contract RootERC20BridgeWithdrawUnitTest is Test, IRootERC20BridgeEvents, IRootE
bytes memory data;

vm.prank(address(mockAxelarAdaptor));
vm.expectRevert(InvalidData.selector);
vm.expectRevert(abi.encodeWithSelector(InvalidData.selector, "Data too short"));

rootBridge.onMessageReceive(CHILD_CHAIN_NAME, CHILD_BRIDGE_ADAPTOR_STRING, data);
}

function test_RevertsIf_OnMessageReceiveWithInvalidSignature() public {
bytes memory data = abi.encode(keccak256("RANDOM"), IMX_TOKEN, address(this), address(this), withdrawAmount);

vm.prank(address(mockAxelarAdaptor));
vm.expectRevert(InvalidData.selector);
vm.expectRevert(abi.encodeWithSelector(InvalidData.selector, "Unsupported action signature"));
rootBridge.onMessageReceive(CHILD_CHAIN_NAME, CHILD_BRIDGE_ADAPTOR_STRING, data);
}

Expand Down

0 comments on commit de91564

Please sign in to comment.