Skip to content

Comments

Implement envOr(...) cheatcodes#1103

Open
RaoulSchaffranek wants to merge 34 commits intomasterfrom
raoul/envOr-cheatcodes
Open

Implement envOr(...) cheatcodes#1103
RaoulSchaffranek wants to merge 34 commits intomasterfrom
raoul/envOr-cheatcodes

Conversation

@RaoulSchaffranek
Copy link
Member

@RaoulSchaffranek RaoulSchaffranek commented Nov 7, 2025

This PR adds envOr(...) cheatcodes.

There are some design choices to consider:

  • Should env variables be read just in time, when the cheatcode call happens, or should env variables be read during initialization? For Simbolik, reading environment variables on demand doesn't make sense because it's running on a server and not on the developer's machine. I think there should be a way to populate environment variables with a new CLI argument, such as --set-env-var name value. These variables are then stored in a new subconfiguration <envVars> and always read from there.
  • What should be the default behavior if a variable is undefined? Particularly for symbolic execution? Should the call return the default value or some fresh variable? Fresh variables sound like the safest option, because they're an overapproximation, but could also lead to more branching.

@lisandrasilva lisandrasilva marked this pull request as draft January 8, 2026 13:54
@lisandrasilva lisandrasilva marked this pull request as ready for review January 13, 2026 10:05
if '=' not in line:
continue
key, value = line.split('=', 1)
key = key.strip()
Copy link
Contributor

Choose a reason for hiding this comment

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

Does strip() also remove inner whitespaces? If not, it would accept some invalid keys, such as MY KEY.

Copy link
Member Author

Choose a reason for hiding this comment

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

@lisandrasilva @anvacaru I think it may be better to use a library for parsing env files, like https://github.com/theskumar/python-dotenv. .env files are more complex than they seem; for example, they typically also allow referencing each other. However, I can also understand if we don't want to introduce another dependency.

@RaoulSchaffranek
Copy link
Member Author

@lisandrasilva @anvacaru I'm wondering what's the best way to propagate environment variables into the initial konfiguration from a user perspective. So far, we're propagating all variables from the .env file in the Foundry root folder. However, we're not propagating variables from the actual environment in which the kontrol command is running.

What do you think about the following approach?

  1. By default, kontrol does not propagate any environment variables!
  2. When kontrol is called with --env argument, it reads all variables from the execution environment.
  3. When kontrol is called with --dot-env filename?, it reads all variables from the given filename, or from the .env file in the Foundry root folder if no filename was provided.

@RaoulSchaffranek
Copy link
Member Author

Additionally, we require a method to initialize environment variables with symbolic values.

@lisandrasilva
Copy link
Contributor

@RaoulSchaffranek,

  1. When kontrol is called with --env argument, it reads all variables from the execution environment.

Isn't it a bit dangerous to read all environment variables, since some of them can contain sensitive information? As a user, I think I would never use this option.

But I do agree with options 1. and 3.

Regarding a method to initialize environment variables with symbolic values, the user can achieve this by providing the default value as a symbolic value rather than a concrete one.

@lisandrasilva
Copy link
Contributor

@RaoulSchaffranek and @anvacaru, right now, the function that I implemented is able to parse the following file:

export UINT256="100" #valid uint with export keyword and as string            
BADUINT256=-100      #invalid uint
  INT256 = -100      #valid int with spaces
BADINT256=notanint
#This is a comment
ADDRESS=0x1234567890123456789012345678901234567890
ADDRESSINT=7584896468543216876435687541650546890874
BADADDRESS=0xGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHSL
BYTES32=0x123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0
BADBYTES32=0xbadbytes32_badbytes32_badbytes32_badbytes32_badbytes32_badbytes3
BOOLFALSE=false
BADBOOLFALSE=notaboolvalue
BOOLTRUE=true
BADBOOLTRUE=notaboolvalue
BYTES=0xdeadbeef
STRING="hello
world" #multiline string
EMPTYSTRING= #empty string
UINT256ARRAY=0,1,2,3,4
INT256ARRAY=-2,-1,0,1,2
ADDRESSARRAY=0x1234567890123456789012345678901234567890,0x2345678901234567890123456789012345678901,0x3456789012345678901234567890123456789012
BYTES32ARRAY=0x123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0,0x15864864541fe8548484c8548654189d4184864a48618c54615156d165651f65,0x7468697264d18561e8691a891968f189868c18969d1868641f1818861685a189
BOOLARRAY=true,false,true,false
STRINGARRAY=one,two

@RaoulSchaffranek I also implemented the --env-file command-line argument that takes a filename for the environment variables; if no filename is provided, it uses .env by default.

Let me know if there's anything else you would like me to address.

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.

3 participants