diff --git a/packages/solidity-mapper/README.md b/packages/solidity-mapper/README.md index c16d5674..84ce23a4 100644 --- a/packages/solidity-mapper/README.md +++ b/packages/solidity-mapper/README.md @@ -35,10 +35,10 @@ $ yarn test * [x] Boolean Type * [x] Address Type * [ ] Fixed-size byte arrays - * [ ] Enum type - * [ ] Dynamically-sized byte array + * [x] Enum type + * [x] Dynamically-sized byte array * [x] Struct Type - * [ ] Mapping Type + * [x] Mapping Type * [ ] Dynamically-sized arrays * [x] Integer Type * [x] Boolean Type @@ -60,9 +60,10 @@ $ yarn test * [x] Get value of a single member in struct * [ ] Reference Types * [x] Struct type members (nested) - * [ ] Array type members - * [ ] Bytes and string type members - * [ ] Mapping type members + * [x] Fixed size Array members + * [ ] Dynamically sized Array members + * [x] Bytes and string type members + * [x] Mapping type members * [ ] Mapping Types * [x] Value Type keys * [ ] Fixed-size byte array keys diff --git a/packages/solidity-mapper/src/storage.test.ts b/packages/solidity-mapper/src/storage.test.ts index 74fe6596..6e0f594e 100644 --- a/packages/solidity-mapper/src/storage.test.ts +++ b/packages/solidity-mapper/src/storage.test.ts @@ -275,7 +275,15 @@ describe('Get value from storage', () => { const int128Array = [100, 200, 300, 400, 500]; const uint16Array = [10, 20, 30, 40, 50]; const boolArray = [true, false]; - let addressArray: string[] = []; + const enumArray = [1, 0, 2, 1, 3, 2]; + const stringArray = ['abcde', 'fg', 'hijklmn']; + + const bytesArray = Array.from({ length: 4 }, () => { + const bytesLength = Math.floor(Math.random() * 64); + return ethers.utils.hexlify(ethers.utils.randomBytes(bytesLength)); + }); + + let addressArray: string[]; before(async () => { const TestFixedArrays = await ethers.getContractFactory('TestFixedArrays'); @@ -284,8 +292,8 @@ describe('Get value from storage', () => { storageLayout = await getStorageLayout('TestFixedArrays'); const signers = await ethers.getSigners(); - addressArray = signers.map(signer => signer.address.toLowerCase()) - .slice(0, 4); + addressArray = signers.slice(0, 4) + .map(signer => signer.address.toLowerCase()); }); // Get all elements of array. @@ -335,14 +343,41 @@ describe('Get value from storage', () => { it.skip('get value for fixed size arrays of fixed size bytes type', async () => { const expectedValue = Array.from({ length: 5 }, () => ethers.utils.hexlify(ethers.utils.randomBytes(10))); - await testFixedArrays.setBytesArray(expectedValue); + await testFixedArrays.setFixedBytesArray(expectedValue); const blockHash = await getBlockHash(); - const { value, proof } = await getStorageValue(storageLayout, getStorageAt, blockHash, testFixedArrays.address, 'bytesArray'); + const { value, proof } = await getStorageValue(storageLayout, getStorageAt, blockHash, testFixedArrays.address, 'fixedBytesArray'); expect(value).to.eql(expectedValue); const proofData = JSON.parse(proof.data); expect(proofData.length).to.equal(expectedValue.length); }); + it('get value for fixed size arrays of enum type', async () => { + await testFixedArrays.setEnumArray(enumArray); + const blockHash = await getBlockHash(); + const { value, proof } = await getStorageValue(storageLayout, getStorageAt, blockHash, testFixedArrays.address, 'enumArray'); + expect(value).to.eql(enumArray.map(el => BigInt(el))); + const proofData = JSON.parse(proof.data); + expect(proofData.length).to.equal(enumArray.length); + }); + + it('get value for fixed size arrays of dynamic byte array type', async () => { + await testFixedArrays.setBytesArray(bytesArray); + const blockHash = await getBlockHash(); + const { value, proof } = await getStorageValue(storageLayout, getStorageAt, blockHash, testFixedArrays.address, 'bytesArray'); + expect(value).to.eql(bytesArray); + const proofData = JSON.parse(proof.data); + expect(proofData.length).to.equal(bytesArray.length); + }); + + it('get value for fixed size arrays of string type', async () => { + await testFixedArrays.setStringArray(stringArray); + const blockHash = await getBlockHash(); + const { value, proof } = await getStorageValue(storageLayout, getStorageAt, blockHash, testFixedArrays.address, 'stringArray'); + expect(value).to.eql(stringArray); + const proofData = JSON.parse(proof.data); + expect(proofData.length).to.equal(stringArray.length); + }); + it('get value for fixed size array of struct type', async () => { const expectedValue = []; @@ -397,6 +432,13 @@ describe('Get value from storage', () => { expect(value).to.equal(addressArray[arrayIndex]); }); + it('get value of enum type array by index', async () => { + const arrayIndex = 3; + const blockHash = await getBlockHash(); + const { value } = await getStorageValue(storageLayout, getStorageAt, blockHash, testFixedArrays.address, 'enumArray', arrayIndex); + expect(value).to.eql(BigInt(enumArray[arrayIndex])); + }); + it('get value of struct type array by index', async () => { const expectedValue = { int1: BigInt(123), @@ -415,6 +457,40 @@ describe('Get value from storage', () => { ({ value } = await getStorageValue(storageLayout, getStorageAt, blockHash, testFixedArrays.address, 'structArray', arrayIndex, structMember)); expect(value).to.eql(expectedValue[structMember]); }); + + it('get value of dynamic bytes type array by index', async () => { + const arrayIndex = 2; + const blockHash = await getBlockHash(); + const { value } = await getStorageValue(storageLayout, getStorageAt, blockHash, testFixedArrays.address, 'bytesArray', arrayIndex); + expect(value).to.eql(bytesArray[arrayIndex]); + }); + + it('get value of string type array by index', async () => { + const arrayIndex = 1; + const blockHash = await getBlockHash(); + const { value } = await getStorageValue(storageLayout, getStorageAt, blockHash, testFixedArrays.address, 'stringArray', arrayIndex); + expect(value).to.eql(stringArray[arrayIndex]); + }); + + it('get value of map type array by index', async () => { + // Set map array values. + const signers = await ethers.getSigners(); + + const mapArrayPromises = signers.slice(0, 3) + .map(async (signer, index) => { + const map = new Map(); + map.set(signer.address, BigInt(index * 10)); + await testFixedArrays.setMapArray(signer.address, map.get(signer.address), index); + return map; + }); + + const arrayIndex = 2; + const mapKey = signers[2].address; + const mapArray = await Promise.all(mapArrayPromises); + const blockHash = await getBlockHash(); + const { value } = await getStorageValue(storageLayout, getStorageAt, blockHash, testFixedArrays.address, 'mapArray', arrayIndex, mapKey); + expect(value).to.equal(mapArray[arrayIndex].get(mapKey)); + }); }); describe('dynamic sized arrays', () => { diff --git a/packages/solidity-mapper/test/contracts/TestBasicMapping.sol b/packages/solidity-mapper/test/contracts/TestBasicMapping.sol index 38f34893..94deec1a 100644 --- a/packages/solidity-mapper/test/contracts/TestBasicMapping.sol +++ b/packages/solidity-mapper/test/contracts/TestBasicMapping.sol @@ -1,5 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.7.6; + +// https://docs.soliditylang.org/en/v0.8.5/layout-of-source-files.html#abi-coder-pragma pragma abicoder v2; contract TestBasicMapping { diff --git a/packages/solidity-mapper/test/contracts/TestDynamicArrays.sol b/packages/solidity-mapper/test/contracts/TestDynamicArrays.sol index 8fbe5cfd..cbaaad7a 100644 --- a/packages/solidity-mapper/test/contracts/TestDynamicArrays.sol +++ b/packages/solidity-mapper/test/contracts/TestDynamicArrays.sol @@ -1,5 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.7.6; + +// https://docs.soliditylang.org/en/v0.8.5/layout-of-source-files.html#abi-coder-pragma pragma abicoder v2; contract TestDynamicArrays { diff --git a/packages/solidity-mapper/test/contracts/TestFixedArrays.sol b/packages/solidity-mapper/test/contracts/TestFixedArrays.sol index bf362443..b572a1b4 100644 --- a/packages/solidity-mapper/test/contracts/TestFixedArrays.sol +++ b/packages/solidity-mapper/test/contracts/TestFixedArrays.sol @@ -1,5 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.7.6; + +// https://docs.soliditylang.org/en/v0.8.5/layout-of-source-files.html#abi-coder-pragma pragma abicoder v2; contract TestFixedArrays { @@ -18,7 +20,15 @@ contract TestFixedArrays { address[4] addressArray; - bytes10[5] bytesArray; + bytes10[5] fixedBytesArray; + + enum Choices { Choice0, Choice1, Choice2, Choice3 } + + Choices[6] enumArray; + + bytes[4] bytesArray; + + string[3] stringArray; struct TestStruct { uint32 uint1; @@ -28,6 +38,8 @@ contract TestFixedArrays { TestStruct[5] structArray; + mapping(address => uint)[3] mapArray; + // Set variable boolArray. function setBoolArray(bool[2] calldata value) external { boolArray = value; @@ -53,13 +65,33 @@ contract TestFixedArrays { addressArray = value; } - // Set variable bytesArray. - function setBytesArray(bytes10[5] calldata value) external { - bytesArray = value; + // Set variable fixedBytesArray. + function setFixedBytesArray(bytes10[5] calldata value) external { + fixedBytesArray = value; } // Set variable structArray. function setStructArray(TestStruct calldata value, uint index) external { structArray[index] = value; } + + // Set variable enumArray. + function setEnumArray(Choices[6] calldata value) external { + enumArray = value; + } + + // Set variable bytesArray. + function setBytesArray(bytes[4] memory value) external { + bytesArray = value; + } + + // Set variable stringArray. + function setStringArray(string[3] memory value) external { + stringArray = value; + } + + // Set variable mapArray. + function setMapArray(address key, uint value, uint index) external { + mapArray[index][key] = value; + } } diff --git a/packages/solidity-mapper/test/contracts/TestNestedArrays.sol b/packages/solidity-mapper/test/contracts/TestNestedArrays.sol index 16860bf6..6fe94761 100644 --- a/packages/solidity-mapper/test/contracts/TestNestedArrays.sol +++ b/packages/solidity-mapper/test/contracts/TestNestedArrays.sol @@ -1,5 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.7.6; + +// https://docs.soliditylang.org/en/v0.8.5/layout-of-source-files.html#abi-coder-pragma pragma abicoder v2; contract TestNestedArrays { diff --git a/packages/solidity-mapper/test/contracts/TestReferenceStructs.sol b/packages/solidity-mapper/test/contracts/TestReferenceStructs.sol index a4c5d522..8e45a39c 100644 --- a/packages/solidity-mapper/test/contracts/TestReferenceStructs.sol +++ b/packages/solidity-mapper/test/contracts/TestReferenceStructs.sol @@ -1,5 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.7.6; + +// https://docs.soliditylang.org/en/v0.8.5/layout-of-source-files.html#abi-coder-pragma pragma abicoder v2; contract TestReferenceStructs { diff --git a/packages/solidity-mapper/test/contracts/TestValueStructs.sol b/packages/solidity-mapper/test/contracts/TestValueStructs.sol index 52f4fd1d..ba0bc482 100644 --- a/packages/solidity-mapper/test/contracts/TestValueStructs.sol +++ b/packages/solidity-mapper/test/contracts/TestValueStructs.sol @@ -1,5 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.7.6; + +// https://docs.soliditylang.org/en/v0.8.5/layout-of-source-files.html#abi-coder-pragma pragma abicoder v2; import "./TestContractTypes.sol";