foundry-rs / foundry

Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.
https://getfoundry.sh
Apache License 2.0
8.12k stars 1.68k forks source link

Yul Compilation #759

Open ControlCplusControlV opened 2 years ago

ControlCplusControlV commented 2 years ago

Component

Forge

Describe the feature you would like

Allow the compilation of Yul Files and the ability to run tests against them. In essence just adding support for compiling and testing .yul Files.

Using a Solidity File containing an interface whose ABI can be specified to be used for a Yul file

Additional context

The Solc compiler has a language option which can be changed to "Yul" to compile the yul files themselves, as far as ABI I've only done it with the Yul+ js package, but if you parse the match case statement in most Yul files and it may make more sense to target Yul+ support first (because sig"" statements can be used to identify Solidity compatible functions) or maybe require a Solidity interface that pairs with each Yul file, whose ABI will be cast on top of said Yul file (akin to YulContract.sol.yul)

Happy to help and talk on Yul support, but my toolchain only works on truffle and want to help bring Yul to foundry, and felt cramming in Yul via FFI would be sloppy vs a direct Yul compilation, especially as if Yul is compile able by foundry, then I can easily add Yul+ support on top.

ControlCplusControlV commented 2 years ago

I am learning rust still, but can provide insight on working with Solc + Yul, and depending on part I can also help with writing rust, but not too familiar with Foundry's codebase so wasn't sure where to start with implementing Yul Support

mattsse commented 2 years ago

foundry uses ethers-solc's solc bindings

https://github.com/gakonst/ethers-rs/blob/f97a8ca5410331145cb742d40ebfe4a816dd3190/ethers-solc/src/compile/mod.rs#L117-L131

Right now we're only supporting solidity and hence only looking for *.sol files.

we're using the standard json input which means that we pipe the CompilerInput as json string to solc's std input:

https://github.com/gakonst/ethers-rs/blob/master/ethers-solc/src/compile/mod.rs#L410-L413

I guess we should start with figuring out how to modify the CompilerInput to support yul, perhaps changing the language is already enough

// Required: Source code language. Currently supported are "Solidity" and "Yul".
  "language": "Solidity",

would you like to try experimenting with that? basically start with adding additional functions for creating a CompilerInput with "Yul" as language: https://github.com/gakonst/ethers-rs/blob/master/ethers-solc/src/artifacts/mod.rs#L53-L61

then try to compile it via solc.compile

https://github.com/gakonst/ethers-rs/blob/master/ethers-solc/src/compile/mod.rs#L438-L452

recmo commented 1 year ago

Standalone Yul is my favorite EVM language. Currently build fails when having more than one .yul file in src/:

$ forge build
[⠰] Compiling...
Error: 
Compiler run failed:
Error: Yul mode only supports exactly one input file.

A workaround is to compile individual contracts:

for f in src/*.{sol,yul}; do forge build -C $f; done;

Another workaround is to introduce the .yul files one by one and rely on the build cache. Somehow the above command does not prime the cache.

zerosnacks commented 2 months ago

Possibly feasible now that multilingual compiler support has landed: https://github.com/foundry-rs/compilers/pull/128