Skip to content

Commit

Permalink
fix(store): revert if slice bound is invalid [L-10] (#2034)
Browse files Browse the repository at this point in the history
Co-authored-by: Kevin Ingersoll <[email protected]>
  • Loading branch information
dk1a and holic authored Jan 18, 2024
1 parent ad4ac44 commit 7b28d32
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 19 deletions.
5 changes: 5 additions & 0 deletions .changeset/perfect-windows-reply.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@latticexyz/store": patch
---

Added a custom error `Store_InvalidBounds` for when the `start:end` slice in `getDynamicFieldSlice` is invalid (it used to revert with the default overflow error)
6 changes: 6 additions & 0 deletions docs/pages/store/reference/store.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,12 @@ error Store_InvalidResourceType(bytes2 expected, ResourceId resourceId, string r
error Store_InvalidStaticDataLength(uint256 expected, uint256 received);
```

### Store_InvalidBounds

```solidity
error Store_InvalidBounds(uint256 start, uint256 end);
```

### Store_IndexOutOfBounds

```solidity
Expand Down
10 changes: 5 additions & 5 deletions packages/store/gas-report.json
Original file line number Diff line number Diff line change
Expand Up @@ -573,25 +573,25 @@
"file": "test/StoreCoreDynamic.t.sol",
"test": "testGetDynamicFieldSlice",
"name": "get field slice (cold, 1 slot)",
"gasUsed": 5609
"gasUsed": 5569
},
{
"file": "test/StoreCoreDynamic.t.sol",
"test": "testGetDynamicFieldSlice",
"name": "get field slice (warm, 1 slot)",
"gasUsed": 1711
"gasUsed": 1671
},
{
"file": "test/StoreCoreDynamic.t.sol",
"test": "testGetDynamicFieldSlice",
"name": "get field slice (semi-cold, 1 slot)",
"gasUsed": 3704
"gasUsed": 3664
},
{
"file": "test/StoreCoreDynamic.t.sol",
"test": "testGetDynamicFieldSlice",
"name": "get field slice (warm, 2 slots)",
"gasUsed": 3931
"gasUsed": 3891
},
{
"file": "test/StoreCoreDynamic.t.sol",
Expand Down Expand Up @@ -1023,7 +1023,7 @@
"file": "test/StoreHooksColdLoad.t.sol",
"test": "testGetItem",
"name": "StoreHooks: get 1 element (cold)",
"gasUsed": 8486
"gasUsed": 8446
},
{
"file": "test/StoreHooksColdLoad.t.sol",
Expand Down
1 change: 1 addition & 0 deletions packages/store/src/IStoreErrors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ interface IStoreErrors {
error Store_InvalidResourceType(bytes2 expected, ResourceId resourceId, string resourceIdString);

error Store_InvalidStaticDataLength(uint256 expected, uint256 received);
error Store_InvalidBounds(uint256 start, uint256 end);
error Store_IndexOutOfBounds(uint256 length, uint256 accessedIndex);
error Store_InvalidKeyNamesLength(uint256 expected, uint256 received);
error Store_InvalidFieldNamesLength(uint256 expected, uint256 received);
Expand Down
8 changes: 7 additions & 1 deletion packages/store/src/StoreCore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -933,6 +933,10 @@ library StoreCore {
uint256 start,
uint256 end
) internal view returns (bytes memory) {
// Verify the slice bounds are valid
if (start > end) {
revert IStoreErrors.Store_InvalidBounds(start, end);
}
// Verify the accessed data is within the bounds of the dynamic field.
// This is necessary because we don't delete the dynamic data when a record is deleted,
// but only decrease its length.
Expand All @@ -945,7 +949,9 @@ library StoreCore {
// Get the length and storage location of the dynamic field
uint256 location = StoreCoreInternal._getDynamicDataLocation(tableId, keyTuple, dynamicFieldIndex);

return Storage.load({ storagePointer: location, offset: start, length: end - start });
unchecked {
return Storage.load({ storagePointer: location, offset: start, length: end - start });
}
}
}

Expand Down
22 changes: 11 additions & 11 deletions packages/world-modules/gas-report.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@
"file": "test/KeysInTableModule.t.sol",
"test": "testSetAndDeleteRecordHookCompositeGas",
"name": "delete a composite record on a table with keysInTableModule installed",
"gasUsed": 155971
"gasUsed": 155851
},
{
"file": "test/KeysInTableModule.t.sol",
Expand All @@ -129,7 +129,7 @@
"file": "test/KeysInTableModule.t.sol",
"test": "testSetAndDeleteRecordHookGas",
"name": "delete a record on a table with keysInTableModule installed",
"gasUsed": 85089
"gasUsed": 85049
},
{
"file": "test/KeysWithValueModule.t.sol",
Expand Down Expand Up @@ -201,31 +201,31 @@
"file": "test/query.t.sol",
"test": "testCombinedHasHasValueNotQuery",
"name": "CombinedHasHasValueNotQuery",
"gasUsed": 104878
"gasUsed": 104518
},
{
"file": "test/query.t.sol",
"test": "testCombinedHasHasValueQuery",
"name": "CombinedHasHasValueQuery",
"gasUsed": 53348
"gasUsed": 53228
},
{
"file": "test/query.t.sol",
"test": "testCombinedHasNotQuery",
"name": "CombinedHasNotQuery",
"gasUsed": 131374
"gasUsed": 130734
},
{
"file": "test/query.t.sol",
"test": "testCombinedHasQuery",
"name": "CombinedHasQuery",
"gasUsed": 84497
"gasUsed": 84137
},
{
"file": "test/query.t.sol",
"test": "testCombinedHasValueNotQuery",
"name": "CombinedHasValueNotQuery",
"gasUsed": 85039
"gasUsed": 84679
},
{
"file": "test/query.t.sol",
Expand All @@ -237,19 +237,19 @@
"file": "test/query.t.sol",
"test": "testHasQuery",
"name": "HasQuery",
"gasUsed": 18882
"gasUsed": 18802
},
{
"file": "test/query.t.sol",
"test": "testHasQuery1000Keys",
"name": "HasQuery with 1000 keys",
"gasUsed": 5804585
"gasUsed": 5764585
},
{
"file": "test/query.t.sol",
"test": "testHasQuery100Keys",
"name": "HasQuery with 100 keys",
"gasUsed": 541538
"gasUsed": 537538
},
{
"file": "test/query.t.sol",
Expand All @@ -261,7 +261,7 @@
"file": "test/query.t.sol",
"test": "testNotValueQuery",
"name": "NotValueQuery",
"gasUsed": 46944
"gasUsed": 46824
},
{
"file": "test/StandardDelegationsModule.t.sol",
Expand Down
4 changes: 2 additions & 2 deletions packages/world/gas-report.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,13 @@
"file": "test/Factories.t.sol",
"test": "testCreate2Factory",
"name": "deploy contract via Create2",
"gasUsed": 4663033
"gasUsed": 4676449
},
{
"file": "test/Factories.t.sol",
"test": "testWorldFactory",
"name": "deploy world via WorldFactory",
"gasUsed": 12501056
"gasUsed": 12514303
},
{
"file": "test/World.t.sol",
Expand Down

0 comments on commit 7b28d32

Please sign in to comment.