-
Notifications
You must be signed in to change notification settings - Fork 326
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
hevm: enchanced control over blockchain context #716
base: master
Are you sure you want to change the base?
Conversation
nix/build-dapp-package.nix
Outdated
@@ -47,6 +48,7 @@ in | |||
'') | |||
passthru.libPaths; | |||
buildPhase = '' | |||
ln -s ${pkgs.writeText "dapprc" dapprc} ./.dapprc |
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.
Instead of this, it could be nice to have the option to pass a dapprc
explicitly as an argument (to dapp build
I guess?).
Another (unrelated) nit is that .dapprc
should probably be (first) looked up in XDG_CONFIG_HOME
(which is not cross-compatible with macOS so would introduce some complexity)
Hey! Yeah, this gets partially at what I was thinking of. The even more powerful thing would actually be what you suggested in chat, a general |
Yeah definitely agree re: the cheat code, but that's a bit of a bigger job for another day. |
Sounds good--and I might still take a crack at it if ever I have some free time 😅 . |
So I ended up adding the cheatcodes. I played around with a cheatcode that could change the address of any contract ( In the end I added the following: /*
allows setting the nonce and balance of an arbitrary account:
hevm.file("nonce", usr, amt)
hevm.file("balance", usr, amt)
*/
hevm.file(bytes32, address, uint)
/*
allows setting the caller, origin, and coinbase:
hevm.file("caller", usr)
hevm.file("origin", usr)
hevm.file("coinbase", usr)
*/
hevm.file(bytes32, address)
/*
allows setting gas price, tx gas limit, block gas limit, and difficulty:
hevm.file("gasPrice", amt)
hevm.file("txGasLimit", amt)
hevm.file("blockGasLimit", amt)
hevm.file("difficulty", amt)
*/
hevm.file(bytes32, uint)
/*
allows reading the nonce for any address:
hevm.look("nonce", usr);
*/
hevm.look(bytes32, address)
/*
allows reading the txGasLimit
hevm.look("txGasLimit");
*/
hevm.look(bytes32)
/*
allows replacing the code at any address (except the currently executing contract)
*/
hevm.replace(address, bytes) I think these give almost exactly the same level of control as the @kmbarry1 I think with |
@@ -2,6 +2,10 @@ | |||
|
|||
## Unreleased | |||
|
|||
### Added |
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.
TODO: document new cheatcodes....
hollllyyyy cow this is amazing @d-xo. only thing that i think is left out that i would kill to have is the ability to change the address of the test contract like you can with |
assertEq(who.balance, bal); | ||
} | ||
|
||
function testReplace() public { |
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 idea why at all, but if I construct the target contract directly with the code below in the test instead of in the constructor this test always fails (and it does so before reaching the call to the cheatcode).... 🤔
function testReplace() public { | |
function testReplace() public { | |
Old target = new Old(); |
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.
Hmm, strange indeed. Does it revert or what is the error?
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.
Failure: testReplace
src/env.sol:CheatCodes
├╴constructor
│ └╴create <unknown contract>@0xCe71065D4017F316EC606Fe4422e11eB2c47c246 <no source map>
│ └╴← 63 bytes of code
└╴testReplace()
└╴error Revert 0x <no source map>
@TransmissionsDev Do you have an example of something that you could do with mutable adresses that you cannot do with mutable code? |
no, just more convenient hehe. if i was forking mainnet and wanted to adopt the address of some authorized user, much easier to just go will still be awesome tho, forgot about the |
assign (env . contracts . (ix usr) . codeOps) $ mkCodeOps newCode | ||
assign (env . contracts . (ix usr) . opIxMap) $ mkOpIxMap newCode | ||
assign (env . contracts . (ix usr) . contractcode) $ RuntimeCode newCode | ||
assign (cache . fetched . (ix usr) . contractcode) $ RuntimeCode newCode |
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.
not sure this is safe. The cache should only contain rpc queries
_ -> vmError (BadCheatCode sig) | ||
_ -> vmError (BadCheatCode sig), | ||
|
||
action "replace(address,bytes)" $ |
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.
an alternative to this could be move(src,dst)
which also moves storage (and nonce and balance?) from the src to dst address
DAPP_TEST_NONCE
env var that allows users to control the nonce assigned to the test contractDAPP_TEST_*
env varscc: @kmbarry1 you were asking for this a while back I believe?