foundry icon indicating copy to clipboard operation
foundry copied to clipboard

Don't keep `CALLER` balance as `U256::MAX`

Open mds1 opened this issue 3 years ago • 11 comments

Component

Forge

Have you ensured that all of these are up to date?

  • [X] Foundry
  • [ ] Foundryup

What version of Foundry are you on?

No response

What command(s) is the bug in?

No response

Operating System

No response

Describe the bug

Here, we set the balance of CALLER and other addresses to U256::MAX to make sure they can execute deploys. https://github.com/foundry-rs/foundry/blob/7e12adbc30d56174320d12be52f94a34d7405c69/forge/src/runner.rs#L69-L71

A few lines below, we set the balances to the user-specified initial balance. https://github.com/foundry-rs/foundry/blob/7e12adbc30d56174320d12be52f94a34d7405c69/forge/src/runner.rs#L128-L131

However, CALLER is left out of there, so if a fuzz test chooses the CALLER address and that test sends ETH to that address, the test reverts with balance overflow.

Proposed fix is to set the CALLER balance after L132 to either 0, or to self.initial_balance. I believe either should be suitable since CALLER isn't used afterwards AFAIK.

This is partially related to #2322 in that I don't think the default balance of an account should ever be kept at U256::MAX, so in that PR I'd suggest using the default self.initial_balance that's typically used instead.

mds1 avatar Jul 19 '22 16:07 mds1

sounds reasonable,

let's set it to self.initial_balance again, setting it to 0 could have side-effects if sender == CALLER I think

mattsse avatar Jul 19 '22 18:07 mattsse

@jferas pointed out to me this happens with another address too:

https://github.com/foundry-rs/foundry/blob/71541ee0c27908e4e90b979f8501149085afa65d/evm/src/executor/mod.rs#L108-L115

I wonder if instead the right solution is to exclude these addresses from the fuzzer dict? 0x3fAB184622Dc19b6109349B94811493BF2a45362 definitely seems safe to exclude because it seems it's only used to deploy the create2 contract, but CALLER maybe is used elsewhere and still should be included?

Either way, 0x3fAB184622Dc19b6109349B94811493BF2a45362 definitely doesn't need a balance of U256::MAX. Let me know what you all think

mds1 avatar Jul 19 '22 20:07 mds1

Unsure, I don't know what that address is being used for. I think it's for script?

onbjerg avatar Jul 20 '22 06:07 onbjerg

that sounds right, wdyt @joshieDo

while we're at it, can we make these constants?

mattsse avatar Jul 20 '22 17:07 mattsse

Reopened because I don't think it resolved https://github.com/foundry-rs/foundry/issues/2390#issuecomment-1189526352

onbjerg avatar Jul 21 '22 19:07 onbjerg

Yep, thanks. Interestingly, @jferas and I both did not see fuzz failures with either of those two addresses until recently, but I don't recall seeing a change that would cause them to start being included in the fuzz dict.

So I think the scope of this issue may be three items:

  1. Reduce the initial balance of 0x3fAB184622Dc19b6109349B94811493BF2a45362 to something smaller.
  2. Make these addresses constants
  3. Decide if these addresses should really be in the fuzz dict or not

Let me know if that sounds right

mds1 avatar Jul 21 '22 20:07 mds1

Hmm, I think self.sender and self.test_address could both be valid inputs(?) and should not be excluded. For CALLER I think we should not have any balance on it before it is actually used - as far as I remember it is only used to call failed() on the test contracts? So potentially CALLER could have it's balance increased in Executor::is_success before the call, and reduced to 0 after the call

onbjerg avatar Jul 21 '22 20:07 onbjerg

Hmm, I think self.sender and self.test_address could both be valid inputs(?) and should not be excluded.

Yea I think I lean this way also, just want to make sure they have more realistic default balances in that case

For CALLER I think we should not have any balance on it before it is actually used - as far as I remember it is only used to call failed() on the test contracts?

Ah ok, yea that seems like a reasonable approach to me then. Perhaps we keep the balance zero, set it to nonzero to call failed(), then reset back to zero after the call?

mds1 avatar Jul 21 '22 20:07 mds1

Ah ok, yea that seems like a reasonable approach to me then. Perhaps we keep the balance zero, set it to nonzero to call failed(), then reset back to zero after the call?

Yea that's what I meant

Yea I think I lean this way also, just want to make sure they have more realistic default balances in that case

Afaik both balances add up to U256::max so it should be safe unless explicitly increased in foundry.toml beyond that. However I do wonder if DappTools used to set the balance of the test caller itself to something other than 0? It would be nice if we could do that but afaik it's not really possible since REVM always does gas accounting and checks the calling account has a balance - if we do the same trick with setting balance > 0 for self.sender before we call a test function and set it to 0 afterwards it wouldn't mean anything since the balance would still be set for the test lol

onbjerg avatar Jul 21 '22 20:07 onbjerg

0x3fAB184622Dc19b6109349B94811493BF2a45362

Does it still have issues with the latest version? Current master branch should handle that

https://github.com/foundry-rs/foundry/blob/f0fa5da3c53858dbf9ac602ffeb633e15c39b9a3/evm/src/executor/mod.rs#L108-L120

joshieDo avatar Jul 24 '22 12:07 joshieDo

The ask is to set it to 0 again after deployment :smile:

onbjerg avatar Jul 24 '22 19:07 onbjerg