Validation checks for the length of asset data

This commit is contained in:
Greg Hysen 2019-06-04 14:09:22 -07:00
parent 1212e534a8
commit e7c4120d24
3 changed files with 44 additions and 1 deletions

View File

@ -163,6 +163,18 @@ contract ERC1155Proxy is
// Load length in bytes of `assetData`
let assetDataLength := calldataload(assetDataOffset)
// Assert that the length of asset data:
// 1. Must be at least 132 bytes (Table #2)
// 2. Must be a multiple of 32 (excluding the 4-byte selector)
if or(lt(assetDataLength, 100), mod(sub(assetDataLength, 4), 32)) {
// Revert with `Error("INVALID_ASSET_DATA_LENGTH")`
mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000)
mstore(64, 0x00000019494e56414c49445f41535345545f444154415f4c454e475448000000)
mstore(96, 0)
revert(0, 100)
}
// End of asset data in calldata
// +32 for length field
let assetDataEnd := add(assetDataOffset, add(assetDataLength, 32))

View File

@ -643,7 +643,7 @@ describe('ERC1155Proxy', () => {
valuesToTransfer,
receiverCallbackData,
);
const extraData = '0102030405060708';
const extraData = '0102030405060708091001020304050607080910010203040506070809100102';
const assetDataWithExtraData = `${assetData}${extraData}`;
// check balances before transfer
const expectedInitialBalances = [spenderInitialFungibleBalance, receiverContractInitialFungibleBalance];
@ -1352,6 +1352,36 @@ describe('ERC1155Proxy', () => {
RevertReason.InvalidDataOffset,
);
});
it('should revert if length of assetData, excluding the selector, is not a multiple of 32', async () => {
// setup test parameters
const tokensToTransfer = fungibleTokens.slice(0, 1);
const valuesToTransfer = [fungibleValueToTransferLarge];
const valueMultiplier = valueMultiplierSmall;
const erc1155ContractAddress = erc1155Wrapper.getContract().address;
const assetData = assetDataUtils.encodeERC1155AssetData(
erc1155ContractAddress,
tokensToTransfer,
valuesToTransfer,
receiverCallbackData,
);
const extraData = '01';
const assetDataWithExtraData = `${assetData}${extraData}`;
// execute transfer
await expectTransactionFailedAsync(
erc1155ProxyWrapper.transferFromWithLogsAsync(
spender,
receiverContract,
erc1155Contract.address,
tokensToTransfer,
valuesToTransfer,
valueMultiplier,
receiverCallbackData,
authorized,
assetDataWithExtraData,
),
RevertReason.InvalidAssetDataLength
);
});
it('should transfer nothing if value is zero', async () => {
// setup test parameters
const tokenHolders = [spender, receiver];

View File

@ -315,6 +315,7 @@ export enum RevertReason {
InvalidIdsOffset = 'INVALID_IDS_OFFSET',
InvalidValuesOffset = 'INVALID_VALUES_OFFSET',
InvalidDataOffset = 'INVALID_DATA_OFFSET',
InvalidAssetDataLength = 'INVALID_ASSET_DATA_LENGTH',
}
export enum StatusCodes {