Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: slot-overwrite bug #133

Closed

Conversation

wei3erHase
Copy link
Member

Fixes #118

@0xGorilla 0xGorilla marked this pull request as draft June 30, 2022 12:56
package.json Outdated
Comment on lines 39 to 41
"mytest:nocompile": "cross-env mocha 'test/unit/mock/mytest.spec.ts'",
"test": "yarn compile && yarn test:nocompile",
"mytest": "yarn compile && yarn mytest:nocompile",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please remove extra scripts from package.json

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

package.json Outdated
@@ -83,7 +84,6 @@
"@types/node": "15.12.2",
"@types/semver": "^7.3.8",
"chai": "4.3.4",
"chai-as-promised": "7.1.1",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why?

Comment on lines 8 to 19
if (isMaybeJsonObject(spec)) {
return await ethersInterfaceFromAbi(spec);
} else {
return await ethersInterfaceFromContractName(spec);
}
} catch (err) {
throw err;
}
return new ethers.utils.Interface(spec);
} catch {}

try {
return (await (hre as any).ethers.getContractFactory(spec)).interface;
} catch {}

try {
return (await (hre as any).ethers.getContractAt(spec, ethers.constants.AddressZero)).interface;
} catch {}

throw new Error(`unable to generate smock spec from string`);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i believe this should not be here, please make sure to pull dev up

Comment on lines 21 to 23
// for (const slot of slots) {
// await this.vmManager.putContractStorage(toFancyAddress(this.contractAddress), fromHexString(slot.key), fromHexString(slot.val));
// }
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

???

await this.vmManager.putContractStorage(toFancyAddress(this.contractAddress), fromHexString(slot.key), fromHexString(slot.val));
let prevStorageValue = await this.vmManager.getContractStorage(toFancyAddress(this.contractAddress), fromHexString(slot.key));
let stringValue = remove0x(toHexString(prevStorageValue));
if (stringValue && (slot.type === 'address' || slot.type === 'bool' || slot.type.startsWith('contract'))) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmm interesting code here, is there any way of generalizing this?
i don't think it will cover all use cases, let's say you have an address, bool, bool pack, would it work?
did you perform tests on multiple scenarios?

Copy link

@wang-jundong wang-jundong Jul 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only address and bool has same slot value
so if they have same slot, previous storage value will be overwritten
i have tested in all case
so i have done this action

// console.log('_______________________________', stringValue, slot.val);
let lastResult = slot.val.slice(0, slot.val.length - stringValue.length).concat(stringValue);
await this.vmManager.putContractStorage(toFancyAddress(this.contractAddress), fromHexString(slot.key), fromHexString(lastResult));
// console.log('>>>>>>>>>>>>>>>>>>>>>>>', slot.key, lastResult);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove comments

Comment on lines 71 to 77
// let storageLayout = (output as any).storageLayout;
// console.log('___ storage ___', (output as any).storageLayout);
// for (let i = 0; i < storageLayout.storage.length; i++) {
// storageLayout.storage[i].slot = i.toString();
// }

// return storageLayout;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rm

@@ -82,6 +90,7 @@ export function computeStorageSlots(storageLayout: SolidityStorageLayout, variab
let slots: StorageSlotPair[] = [];
for (const [variableName, variableValue] of Object.entries(variables)) {
// Find the entry in the storage layout that corresponds to this variable name.
// console.log('___ variableName, variableValue ___', variableName, variableValue);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rm rm rm

Comment on lines 103 to 104
// console.log('___ storageObj ___', storageObj);
// console.log('___ slots before ___', slots);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rrrrrrrrrrrrmmmmmmmmm

Comment on lines 2 to 7
pragma solidity ^0.8.4;

contract Bug {
address public myAddress;
bool public myBool;
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please generalize to different cases

Copy link
Member Author

@wei3erHase wei3erHase left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ey wang! let me generalize some comments:

  • i see a lot of extra comments that shouldn't be there, please rm
  • also, there are changes in dev that you seem to be rolling back, please correct
  • i like the solution, but i'm not convinced it could address all possible scenarios, please convince us

thanks for contributing to smock! 🚀
i see lot of potential here

Copy link
Member Author

@wei3erHase wei3erHase left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please, go into Files changed on the Pull Request and make sure that you commit to all the changes that appear there, this doesn't seem to be mergeable without removing other features.

package.json Outdated
@@ -74,7 +74,6 @@
"@typechain/ethers-v5": "7.0.1",
"@typechain/hardhat": "2.0.2",
"@types/chai": "4.2.18",
"@types/chai-as-promised": "7.1.5",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are we removing this import?

Comment on lines 26 to 31
console.log('____myAddress____', await mock.myAddress());
console.log('____myBool____', await mock.myBool());
console.log('____newAddress____', await mock.newAddress());
console.log('____newAddress2____', await mock.newAddress2());
console.log('____newBool____', await mock.newBool());
console.log('____newBool2____', await mock.newBool2());
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please, remove all console.logs...

@@ -0,0 +1,25 @@
import { MockContract, MockContractFactory, smock } from '@src';
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this file named mytest.spec2.ts??

});

describe('setVariable', () => {
it('should be able to fix bug', async () => {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't reference the bug, this will stay in documentation for the future

* @title Storage
* @dev Store & retrieve value in a variable
*/
contract Storage {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

emmm, should we keep this one?

Comment on lines 5 to 7
export const ADDRESS_EXAMPLE2 = '0x4fd96172C40913c8100a47337f21DBf25C9e2fC6';

export const ADDRESS_EXAMPLE3 = '0x62eA762d9f2672f82d26b94f56849881831B9eaB';
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i prefer you added a _ before the numbers


describe('setVariable', () => {
it('should not be able to overwrite slot', async () => {
await mock.setVariable('myAddress', ADDRESS_EXAMPLE);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to use any ADDRESS_EXAMPLEX, let just use generated random addresses, I believe we can achieve that with makeRandomAddress()

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about using setVariables instead of so many setVariable

Comment on lines 94 to 110

it('should throw error for invalid json string abi', async () => {
await expect(smock.fake(`{invalid}`)).to.be.rejectedWith(
Error,
`unable to generate smock spec from abi string.\nUnexpected token i in JSON at position 1`
);
});

it('should throw error for non existent contract', async () => {
let regex: RegExp = /unable to generate smock spec from contract name*/;
await expect(smock.fake('NonExistentContract')).to.be.rejectedWith(Error, regex);
});

it('should throw error if contract name is ambiguous', async () => {
let regex: RegExp = /unable to generate smock spec from contract name*/;
await expect(smock.fake('Storage')).to.be.rejectedWith(Error, regex);
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why deleting this??

@@ -1,26 +0,0 @@
// SPDX-License-Identifier: MIT
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was being used for the test: should throw error if contract name is ambiguous. Why deleting it?

@@ -1,26 +0,0 @@
// SPDX-License-Identifier: MIT
Copy link
Member

@0xGorilla 0xGorilla Jul 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose you are now using SlotOverwrite instead of this file, right?

});

describe('setVariable', () => {
it('should not be able to overwrite slot', async () => {
Copy link
Member

@0xGorilla 0xGorilla Jul 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's please try more types, bytes, utint, etc... Maybe add some more tests

let prevStorageValue = await this.vmManager.getContractStorage(toFancyAddress(this.contractAddress), fromHexString(slot.key));
let stringValue = remove0x(toHexString(prevStorageValue));
if (stringValue && (slot.type === 'address' || slot.type === 'bool' || slot.type.startsWith('contract'))) {
let lastResult = slot.val.slice(0, slot.val.length - stringValue.length).concat(stringValue);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how come this works if you are always slicing starting in index 0? What if the variable packed slot starts from the middle?

@wei3erHase
Copy link
Member Author

Checked until here.
Needs to test more data types.

@wei3erHase
Copy link
Member Author

provided test does not replicate bug behaviour

@wei3erHase
Copy link
Member Author

Closing PR due to misunderstanding of task scope.

@wei3erHase wei3erHase closed this Jul 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Fix slot overwrite on packed variables
4 participants