Skip to content
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

build: simultaneously compilation #1106

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .github/workflows/ci-deep.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ jobs:
uses: "sablier-labs/reusable-workflows/.github/workflows/forge-test.yml@main"
with:
foundry-fuzz-runs: ${{ fromJSON(inputs.unitFuzzRuns || '50000') }}
foundry-profile: "test-optimized"
match-path: "tests/unit/**/*.sol"
name: "Unit tests"

Expand All @@ -50,7 +49,6 @@ jobs:
uses: "sablier-labs/reusable-workflows/.github/workflows/forge-test.yml@main"
with:
foundry-fuzz-runs: ${{ fromJSON(inputs.integrationFuzzRuns || '50000') }}
foundry-profile: "test-optimized"
match-path: "tests/integration/**/*.sol"
name: "Integration tests"

Expand All @@ -60,7 +58,6 @@ jobs:
with:
foundry-invariant-depth: ${{ fromJSON(inputs.invariantDepth || '100') }}
foundry-invariant-runs: ${{ fromJSON(inputs.invariantRuns || '100') }}
foundry-profile: "test-optimized"
match-path: "tests/invariant/**/*.sol"
name: "Invariant tests"

Expand All @@ -71,7 +68,6 @@ jobs:
uses: "sablier-labs/reusable-workflows/.github/workflows/forge-test.yml@main"
with:
foundry-fuzz-runs: ${{ fromJSON(inputs.forkFuzzRuns || '1000') }}
foundry-profile: "test-optimized"
match-path: "tests/fork/**/*.sol"
name: "Fork tests"

Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/ci-fork.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ jobs:
uses: "sablier-labs/reusable-workflows/.github/workflows/forge-test.yml@main"
with:
foundry-fuzz-runs: 100
foundry-profile: "test-optimized"
fuzz-seed: true
match-path: "tests/fork/**/*.sol"
name: "Fork tests"
Expand All @@ -27,7 +26,6 @@ jobs:
needs: ["lint", "build"]
uses: "sablier-labs/reusable-workflows/.github/workflows/forge-test.yml@main"
with:
foundry-profile: "test-optimized"
match-path: "tests/utils/**/*.sol"
name: "Utils tests"

Expand Down
4 changes: 0 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ jobs:
uses: "sablier-labs/reusable-workflows/.github/workflows/forge-test.yml@main"
with:
foundry-fuzz-runs: 2000
foundry-profile: "test-optimized"
match-path: "tests/unit/**/*.sol"
name: "Unit tests"

Expand All @@ -41,15 +40,13 @@ jobs:
uses: "sablier-labs/reusable-workflows/.github/workflows/forge-test.yml@main"
with:
foundry-fuzz-runs: 2000
foundry-profile: "test-optimized"
match-path: "tests/integration/**/*.sol"
name: "Integration tests"

test-invariant:
needs: ["lint", "build"]
uses: "sablier-labs/reusable-workflows/.github/workflows/forge-test.yml@main"
with:
foundry-profile: "test-optimized"
match-path: "tests/invariant/**/*.sol"
name: "Invariant tests"

Expand All @@ -60,7 +57,6 @@ jobs:
uses: "sablier-labs/reusable-workflows/.github/workflows/forge-test.yml@main"
with:
foundry-fuzz-runs: 20
foundry-profile: "test-optimized"
match-path: "tests/fork/**/*.sol"
name: "Fork tests"

Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ deployments
docs
node_modules
out
out-optimized
out-svg

# files
Expand Down
1 change: 0 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ coverage
docs
node_modules
out
out-optimized
out-svg

# files
Expand Down
38 changes: 18 additions & 20 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,18 @@
bytecode_hash = "none"
evm_version = "shanghai"
fs_permissions = [
{ access = "read", path = "./out-optimized" },
{ access = "read", path = "./out" },
{ access = "read", path = "package.json" },
{ access = "read-write", path = "./benchmark/results" },
{ access = "read-write", path = "./script/"}
]
gas_limit = 9223372036854775807
# https://book.getfoundry.sh/reference/config/solidity-compiler#libraries
# TODO: Update addresses once deployed.
libraries = [
"src/libraries/Helpers.sol:Helpers:0x7715bE116061E014Bb721b46Dc78Dd57C91FDF9b",
"src/libraries/VestingMath.sol:VestingMath:0x26F9d826BDed47Fc472526aE8095B75ac336963C"
]
optimizer = true
optimizer_runs = 1000
out = "out"
Expand All @@ -17,6 +23,7 @@
solc = "0.8.26"
src = "src"
test = "tests"
via_ir = true

[profile.default.fuzz]
max_test_rejects = 1_000_000 # Number of times `vm.assume` can fail
Expand All @@ -28,36 +35,31 @@
fail_on_revert = true
runs = 20

additional_compiler_profiles = [
{ name = "tests/", via_ir = false }
]

compilation_restrictions = [
{ paths = "tests/mocks", via_ir = true },
{ paths = "tests/**", via_ir = false }
]

# Run only the code inside benchmark directory
[profile.benchmark]
test = "benchmark"

# Speed up compilation and tests during development
[profile.lite]
optimizer = false

# Compile only the production code and the test mocks with via IR
[profile.optimized]
# https://book.getfoundry.sh/reference/config/solidity-compiler#libraries
# TODO: Update addresses once deployed.
libraries = [
"src/libraries/Helpers.sol:Helpers:0x7715bE116061E014Bb721b46Dc78Dd57C91FDF9b",
"src/libraries/VestingMath.sol:VestingMath:0x26F9d826BDed47Fc472526aE8095B75ac336963C"
]
out = "out-optimized"
test = "tests/mocks"
via_ir = true

via_ir = false

# See "SMTChecker and Formal Verification" in the Solidity docs
[profile.smt]
ignored_error_codes = [
7737, # Disable inline assembly warnings
]
out = "out-optimized"
script = "src"
test = "src"
via_ir = true

[profile.smt.model_checker]
engine = "chc" # constrained Horn clauses
Expand All @@ -79,10 +81,6 @@
"src/LockupNFTDescriptor.sol" = ["LockupNFTDescriptor"]
"src/SablierLockup.sol" = ["SablierLockup"]

# Test the optimized contracts without re-compiling them
[profile.test-optimized]
src = "tests"

[doc]
ignore = ["**/*.t.sol"]
out = "docs"
Expand Down
8 changes: 3 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,10 @@
},
"repository": "github.com/sablier-labs/lockup",
"scripts": {
"benchmark": "bun run build:optimized && FOUNDRY_PROFILE=benchmark forge test --mt testGas && bun run prettier:write",
"benchmark": "bun run build && FOUNDRY_PROFILE=benchmark forge test --mt testGas && bun run prettier:write",
"build": "forge build",
"build:optimized": "FOUNDRY_PROFILE=optimized forge build",
"build:smt": "FOUNDRY_PROFILE=smt forge build",
"clean": "rm -rf artifacts broadcast cache docs out out-optimized out-svg",
"clean": "rm -rf artifacts broadcast cache docs out out-svg",
"lint": "bun run lint:sol && bun run prettier:check",
"lint:fix": "bun run lint:sol:fix && forge fmt",
"lint:sol": "forge fmt --check && bun solhint \"{benchmark,precompiles,script,src,tests}/**/*.sol\"",
Expand All @@ -76,7 +75,6 @@
"prettier:check": "prettier --check \"**/*.{json,md,svg,yml}\"",
"prettier:write": "prettier --write \"**/*.{json,md,svg,yml}\"",
"test": "forge test",
"test:lite": "FOUNDRY_PROFILE=lite forge test",
"test:optimized": "bun run build:optimized && FOUNDRY_PROFILE=test-optimized forge test"
"test:lite": "FOUNDRY_PROFILE=lite forge test --nmt \"testFork\" --nmc \"Precompiles_Test\""
}
}
6 changes: 3 additions & 3 deletions precompiles/Precompiles.sol

Large diffs are not rendered by default.

30 changes: 15 additions & 15 deletions shell/prepare-artifacts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
set -euo pipefail

# Generate the artifacts with Forge
FOUNDRY_PROFILE=optimized forge build
forge build

# Delete the current artifacts
artifacts=./artifacts
Expand All @@ -26,33 +26,33 @@ mkdir $artifacts \
################################################

lockup=./artifacts/
cp out-optimized/LockupNFTDescriptor.sol/LockupNFTDescriptor.json $lockup
cp out-optimized/SablierLockup.sol/SablierLockup.json $lockup
cp out-optimized/SablierBatchLockup.sol/SablierBatchLockup.json $lockup
cp out/LockupNFTDescriptor.sol/LockupNFTDescriptor.json $lockup
cp out/SablierLockup.sol/SablierLockup.json $lockup
cp out/SablierBatchLockup.sol/SablierBatchLockup.json $lockup

lockup_interfaces=./artifacts/interfaces
cp out-optimized/ISablierBatchLockup.sol/ISablierBatchLockup.json $lockup_interfaces
cp out-optimized/ILockupNFTDescriptor.sol/ILockupNFTDescriptor.json $lockup_interfaces
cp out-optimized/ISablierLockupRecipient.sol/ISablierLockupRecipient.json $lockup_interfaces
cp out-optimized/ISablierLockupBase.sol/ISablierLockupBase.json $lockup_interfaces
cp out-optimized/ISablierLockup.sol/ISablierLockup.json $lockup_interfaces
cp out/ISablierBatchLockup.sol/ISablierBatchLockup.json $lockup_interfaces
cp out/ILockupNFTDescriptor.sol/ILockupNFTDescriptor.json $lockup_interfaces
cp out/ISablierLockupRecipient.sol/ISablierLockupRecipient.json $lockup_interfaces
cp out/ISablierLockupBase.sol/ISablierLockupBase.json $lockup_interfaces
cp out/ISablierLockup.sol/ISablierLockup.json $lockup_interfaces

lockup_libraries=./artifacts/libraries
cp out-optimized/Errors.sol/Errors.json $lockup_libraries
cp out-optimized/Helpers.sol/Helpers.json $lockup_libraries
cp out-optimized/VestingMath.sol/VestingMath.json $lockup_libraries
cp out/Errors.sol/Errors.json $lockup_libraries
cp out/Helpers.sol/Helpers.json $lockup_libraries
cp out/VestingMath.sol/VestingMath.json $lockup_libraries


################################################
#### OTHERS ####
################################################

erc20=./artifacts/erc20
cp out-optimized/IERC20.sol/IERC20.json $erc20
cp out/IERC20.sol/IERC20.json $erc20

erc721=./artifacts/erc721
cp out-optimized/IERC721.sol/IERC721.json $erc721
cp out-optimized/IERC721Metadata.sol/IERC721Metadata.json $erc721
cp out/IERC721.sol/IERC721.json $erc721
cp out/IERC721Metadata.sol/IERC721Metadata.json $erc721

# Format the artifacts with Prettier
bun prettier --write ./artifacts
4 changes: 2 additions & 2 deletions shell/update-counts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ set -euo pipefail
# Path to the Base Script
BASE_SCRIPT="script/Base.s.sol"

# Compile the contracts with the optimized profile
bun run build:optimized
# Compile the contracts
bun run build

# Generalized function to update counts
update_counts() {
Expand Down
8 changes: 4 additions & 4 deletions shell/update-precompiles.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
set -euo pipefail

# Compile the contracts with Forge
FOUNDRY_PROFILE=optimized forge build
forge build

# Retrieve the raw bytecodes, removing the "0x" prefix
batch_lockup=$(cat out-optimized/SablierBatchLockup.sol/SablierBatchLockup.json | jq -r '.bytecode.object' | cut -c 3-)
lockup=$(cat out-optimized/SablierLockup.sol/SablierLockup.json | jq -r '.bytecode.object' | cut -c 3-)
nft_descriptor=$(cat out-optimized/LockupNFTDescriptor.sol/LockupNFTDescriptor.json | jq -r '.bytecode.object' | cut -c 3-)
batch_lockup=$(cat out/SablierBatchLockup.sol/SablierBatchLockup.json | jq -r '.bytecode.object' | cut -c 3-)
lockup=$(cat out/SablierLockup.sol/SablierLockup.json | jq -r '.bytecode.object' | cut -c 3-)
nft_descriptor=$(cat out/LockupNFTDescriptor.sol/LockupNFTDescriptor.json | jq -r '.bytecode.object' | cut -c 3-)

precompiles_path="precompiles/Precompiles.sol"
if [ ! -f $precompiles_path ]; then
Expand Down
12 changes: 2 additions & 10 deletions tests/Base.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { ILockupNFTDescriptor } from "src/interfaces/ILockupNFTDescriptor.sol";
import { ISablierBatchLockup } from "src/interfaces/ISablierBatchLockup.sol";
import { ISablierLockup } from "src/interfaces/ISablierLockup.sol";
import { LockupNFTDescriptor } from "src/LockupNFTDescriptor.sol";
import { SablierBatchLockup } from "src/SablierBatchLockup.sol";
import { SablierLockup } from "src/SablierLockup.sol";
import { Lockup, LockupDynamic, LockupLinear, LockupTranched } from "src/types/DataTypes.sol";

import { ERC20MissingReturn } from "./mocks/erc20/ERC20MissingReturn.sol";
Expand Down Expand Up @@ -144,13 +141,8 @@ abstract contract Base_Test is Assertions, Calculations, DeployOptimized, Modifi
/// deployer's nonce, which would in turn lead to different addresses (recall that the addresses
/// for contracts deployed via `CREATE` are based on the caller-and-nonce-hash).
function deployProtocolConditionally() internal {
if (!isBenchmarkProfile() && !isTestOptimizedProfile()) {
batchLockup = new SablierBatchLockup();
nftDescriptor = new LockupNFTDescriptor();
lockup = new SablierLockup(users.admin, nftDescriptor, defaults.MAX_COUNT());
} else {
(nftDescriptor, lockup, batchLockup) = deployOptimizedProtocol(users.admin, defaults.MAX_COUNT());
}
(nftDescriptor, lockup, batchLockup) = deployOptimizedProtocol(users.admin, defaults.MAX_COUNT());

vm.label({ account: address(batchLockup), newLabel: "BatchLockup" });
vm.label({ account: address(lockup), newLabel: "Lockup" });
vm.label({ account: address(nftDescriptor), newLabel: "NFTDescriptor" });
Expand Down
8 changes: 2 additions & 6 deletions tests/unit/shared/Adminable.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,8 @@ abstract contract Adminable_Unit_Shared_Test is Base_Test {

/// @dev Conditionally deploys {AdminableMock} normally or from a source precompiled with `--via-ir`.
function deployConditionally() internal {
if (!isTestOptimizedProfile()) {
adminableMock = new AdminableMock(users.admin);
} else {
adminableMock =
AdminableMock(deployCode("out-optimized/AdminableMock.sol/AdminableMock.json", abi.encode(users.admin)));
}
adminableMock = AdminableMock(deployCode("out/AdminableMock.sol/AdminableMock.json", abi.encode(users.admin)));

vm.label({ account: address(adminableMock), newLabel: "AdminableMock" });
}
}
11 changes: 5 additions & 6 deletions tests/utils/DeployOptimized.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ import { ISablierLockup } from "../../src/interfaces/ISablierLockup.sol";
abstract contract DeployOptimized is StdCheats, CommonBase {
/// @dev Deploys {SablierBatchLockup} from an optimized source compiled with `--via-ir`.
function deployOptimizedBatchLockup() internal returns (ISablierBatchLockup) {
return ISablierBatchLockup(deployCode("out-optimized/SablierBatchLockup.sol/SablierBatchLockup.json"));
return ISablierBatchLockup(deployCode("out/SablierBatchLockup.sol/SablierBatchLockup.json"));
}

/// @dev Deploys the optimized {Helpers} and {VestingMath} libraries and assign them to linked addresses.
function deployOptimizedLibraries() internal {
address helpers = deployCode("out-optimized/Helpers.sol/Helpers.json");
address vestingMath = deployCode("out-optimized/VestingMath.sol/VestingMath.json");
address helpers = deployCode("out/Helpers.sol/Helpers.json");
address vestingMath = deployCode("out/VestingMath.sol/VestingMath.json");
vm.etch(0x7715bE116061E014Bb721b46Dc78Dd57C91FDF9b, helpers.code);
vm.etch(0x26F9d826BDed47Fc472526aE8095B75ac336963C, vestingMath.code);
}
Expand All @@ -37,15 +37,14 @@ abstract contract DeployOptimized is StdCheats, CommonBase {
// Deploy the Lockup contract.
return ISablierLockup(
deployCode(
"out-optimized/SablierLockup.sol/SablierLockup.json",
abi.encode(initialAdmin, address(nftDescriptor_), maxCount)
"out/SablierLockup.sol/SablierLockup.json", abi.encode(initialAdmin, address(nftDescriptor_), maxCount)
)
);
}

/// @dev Deploys {LockupNFTDescriptor} from an optimized source compiled with `--via-ir`.
function deployOptimizedNFTDescriptor() internal returns (ILockupNFTDescriptor) {
return ILockupNFTDescriptor(deployCode("out-optimized/LockupNFTDescriptor.sol/LockupNFTDescriptor.json"));
return ILockupNFTDescriptor(deployCode("out/LockupNFTDescriptor.sol/LockupNFTDescriptor.json"));
}

/// @notice Deploys all contracts from an optimized source compiled with `--via-ir` in the following order:
Expand Down
Loading
Loading