This is a proof of concept to enable multi-version Solidity projects with Foundry.
This example uses Solidity 0.6.12
and 0.8.14
, but in theory it could work for any two or more versions.
- Use Foundry built-in profiles for different Solidity versions.
Use the
default
profile for the "main" version (0.8.14
in this case). - Have separate
src
directories for each version. - Have separate
lib
directories for each version, but allow the non-default versions to pull compatible dependencies from the default one. - Test files and Solidity scripts go into the
src
directories and not in separatetest
andscript
ones.
Compile the non-default versions first:
FOUNDRY_PROFILE=0_6_x forge build
Compile the default version last:
forge build
forge
will overwrite the compiled files in out/
for whichever contracts that were compiled with
FOUNDRY_PROFILE=0_6_x
with the compiled files using the default profile. In other words, any contracts that were
accessible with the 0.6.x
compiler will be overwritten by the default profile using Solidity 0.8.x
if the commands
are run in the order above. Keep that in mind if you are using this approach to deploy contracts, you might end up
submitting the bytecode generated by a different compiler version than what you intended.
To reference contracts from compiled with versions, use the getCode()
cheat code.
pragma solidity ^0.8.14;
import "forge-std/Test.sol";
contract MyTest is Test {
Contract myContract = new Contract();
function testDeployContractWithAnotherVersion() public {
address anotherAddress = deployCode("Contract6.sol:Contract6");
// Different compiler versions will produce different bytecodes
assertTrue(keccak256(address(myContract).code) != keccak256(anotherAddress.code)); // [PASS]
}
}