diff --git a/contracts/handlers/DepositDataHelper.sol b/contracts/handlers/DepositDataHelper.sol index a157646c..5f84ad28 100644 --- a/contracts/handlers/DepositDataHelper.sol +++ b/contracts/handlers/DepositDataHelper.sol @@ -10,6 +10,8 @@ import "../interfaces/ISygmaMessageReceiver.sol"; @author ChainSafe Systems. */ contract DepositDataHelper is ERCHandlerHelpers { + using SanityChecks for *; + address public immutable _defaultMessageReceiver; uint16 internal constant maxReturnBytes = 256; address internal constant transformRecipient = address(0); @@ -54,13 +56,14 @@ contract DepositDataHelper is ERCHandlerHelpers { uint256 lenDestinationRecipientAddress; (amount, lenDestinationRecipientAddress) = abi.decode(data, (uint256, uint256)); - address recipientAddress = address(bytes20(bytes(data[64:64 + lenDestinationRecipientAddress]))); + lenDestinationRecipientAddress.mustBe(20); + address recipientAddress = address(bytes20(bytes(data[64:84]))); address tokenAddress = _resourceIDToTokenContractAddress[resourceID]; uint256 externalAmount = convertToExternalBalance(tokenAddress, amount); // Optional message recipient transformation. - uint256 pointer = 64 + lenDestinationRecipientAddress; + uint256 pointer = 84; uint256 gas; uint256 messageLength; bytes memory message; diff --git a/contracts/handlers/ERC1155Handler.sol b/contracts/handlers/ERC1155Handler.sol index a2d894b1..b11a531f 100644 --- a/contracts/handlers/ERC1155Handler.sol +++ b/contracts/handlers/ERC1155Handler.sol @@ -71,6 +71,7 @@ contract ERC1155Handler is IHandler, ERCHandlerHelpers, ERC1155Safe, ERC1155Hold (tokenIDs, amounts, recipient, transferData) = abi.decode(data, (uint[], uint[], bytes, bytes)); + recipient.length.mustBe(20); bytes20 recipientAddress; assembly { diff --git a/contracts/handlers/ERC721Handler.sol b/contracts/handlers/ERC721Handler.sol index 6f8fa9b0..c5fcaa72 100644 --- a/contracts/handlers/ERC721Handler.sol +++ b/contracts/handlers/ERC721Handler.sol @@ -92,7 +92,8 @@ contract ERC721Handler is IHandler, ERCHandlerHelpers, ERC721Safe { bytes memory metaData; (tokenID, lenDestinationRecipientAddress) = abi.decode(data, (uint, uint)); - offsetMetaData = 64 + lenDestinationRecipientAddress; + lenDestinationRecipientAddress.mustBe(20); + offsetMetaData = 84; destinationRecipientAddress = bytes(data[64:offsetMetaData]); lenMetaData = abi.decode(data[offsetMetaData:], (uint)); metaData = bytes(data[offsetMetaData + 32:offsetMetaData + 32 + lenMetaData]); diff --git a/contracts/handlers/GmpHandler.sol b/contracts/handlers/GmpHandler.sol index 229acce1..2a63bbc1 100644 --- a/contracts/handlers/GmpHandler.sol +++ b/contracts/handlers/GmpHandler.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.11; import "../interfaces/IHandler.sol"; +import "../utils/SanityChecks.sol"; /** @title Handles generic deposits and deposit executions. @@ -10,6 +11,8 @@ import "../interfaces/IHandler.sol"; @notice This contract is intended to be used with the Bridge contract. */ contract GmpHandler is IHandler { + using SanityChecks for *; + uint256 public constant MAX_FEE = 1000000; address public immutable _bridgeAddress; @@ -165,10 +168,13 @@ contract GmpHandler is IHandler { maxFee = uint256(bytes32(data[:pointer += 32])); lenExecuteFuncSignature = uint16(bytes2(data[pointer:pointer += 2])); + lenExecuteFuncSignature.mustBe(4); executeFuncSignature = bytes4(data[pointer:pointer += lenExecuteFuncSignature]); lenExecuteContractAddress = uint8(bytes1(data[pointer:pointer += 1])); + lenExecuteContractAddress.mustBe(20); executeContractAddress = address(uint160(bytes20(data[pointer:pointer += lenExecuteContractAddress]))); lenExecutionDataDepositor = uint8(bytes1(data[pointer:pointer += 1])); + lenExecutionDataDepositor.mustBe(20); executionDataDepositor = address(uint160(bytes20(data[pointer:pointer += lenExecutionDataDepositor]))); executionData = bytes(data[pointer:]); diff --git a/contracts/handlers/XC20Handler.sol b/contracts/handlers/XC20Handler.sol index 3c9b01ec..a6e9c393 100644 --- a/contracts/handlers/XC20Handler.sol +++ b/contracts/handlers/XC20Handler.sol @@ -72,7 +72,8 @@ contract XC20Handler is IHandler, ERCHandlerHelpers, XC20Safe { bytes memory destinationRecipientAddress; (amount, lenDestinationRecipientAddress) = abi.decode(data, (uint, uint)); - destinationRecipientAddress = bytes(data[64:64 + lenDestinationRecipientAddress]); + lenDestinationRecipientAddress.mustBe(20); + destinationRecipientAddress = bytes(data[64:84]); bytes20 recipientAddress; address tokenAddress = _resourceIDToTokenContractAddress[resourceID]; diff --git a/contracts/utils/SanityChecks.sol b/contracts/utils/SanityChecks.sol index 976f7ee7..50a9fb64 100644 --- a/contracts/utils/SanityChecks.sol +++ b/contracts/utils/SanityChecks.sol @@ -8,9 +8,15 @@ pragma solidity 0.8.11; */ library SanityChecks { error ZeroAddress(); + error UnexpectedValue(uint256 actual, uint256 expected); function mustNotBeZero(address addr) internal pure returns(address) { if (addr == address(0)) revert ZeroAddress(); return addr; } + + function mustBe(uint256 actual, uint256 expected) internal pure returns(uint256) { + if (actual != expected) revert UnexpectedValue(actual, expected); + return actual; + } }