-
Notifications
You must be signed in to change notification settings - Fork 41
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
Conversation
package.json
Outdated
"mytest:nocompile": "cross-env mocha 'test/unit/mock/mytest.spec.ts'", | ||
"test": "yarn compile && yarn test:nocompile", | ||
"mytest": "yarn compile && yarn mytest:nocompile", |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why?
src/factories/ethers-interface.ts
Outdated
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`); |
There was a problem hiding this comment.
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
src/logic/editable-storage-logic.ts
Outdated
// for (const slot of slots) { | ||
// await this.vmManager.putContractStorage(toFancyAddress(this.contractAddress), fromHexString(slot.key), fromHexString(slot.val)); | ||
// } |
There was a problem hiding this comment.
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'))) { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
src/logic/editable-storage-logic.ts
Outdated
// 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); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove comments
src/utils/storage.ts
Outdated
// 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; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rm
src/utils/storage.ts
Outdated
@@ -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); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rm rm rm
src/utils/storage.ts
Outdated
// console.log('___ storageObj ___', storageObj); | ||
// console.log('___ slots before ___', slots); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rrrrrrrrrrrrmmmmmmmmm
test/contracts/mock/Bug.sol
Outdated
pragma solidity ^0.8.4; | ||
|
||
contract Bug { | ||
address public myAddress; | ||
bool public myBool; | ||
} |
There was a problem hiding this comment.
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
There was a problem hiding this 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
There was a problem hiding this 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", |
There was a problem hiding this comment.
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?
test/unit/mock/mytest.spec.ts
Outdated
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()); |
There was a problem hiding this comment.
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...
test/unit/mock/mytest.spec2.ts
Outdated
@@ -0,0 +1,25 @@ | |||
import { MockContract, MockContractFactory, smock } from '@src'; |
There was a problem hiding this comment.
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
??
test/unit/mock/mytest.spec2.ts
Outdated
}); | ||
|
||
describe('setVariable', () => { | ||
it('should be able to fix bug', async () => { |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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?
test/utils/constants.ts
Outdated
export const ADDRESS_EXAMPLE2 = '0x4fd96172C40913c8100a47337f21DBf25C9e2fC6'; | ||
|
||
export const ADDRESS_EXAMPLE3 = '0x62eA762d9f2672f82d26b94f56849881831B9eaB'; |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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()
There was a problem hiding this comment.
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
|
||
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); | ||
}); |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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 () => { |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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?
Checked until here. |
provided test does not replicate bug behaviour |
Closing PR due to misunderstanding of task scope. |
Fixes #118