diff --git a/benchmark/BatchLockup.Gas.t.sol b/benchmark/BatchLockup.Gas.t.sol new file mode 100644 index 000000000..1cf8e5d2e --- /dev/null +++ b/benchmark/BatchLockup.Gas.t.sol @@ -0,0 +1,259 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.8.22; + +import { ud2x18 } from "@prb/math/src/UD2x18.sol"; + +import { LockupDynamic, LockupLinear, LockupTranched } from "../src/core/types/DataTypes.sol"; +import { BatchLockup } from "../src/periphery/types/DataTypes.sol"; +import { BatchLockupBuilder } from "../test/utils/BatchLockupBuilder.sol"; + +import { Benchmark_Test } from "./Benchmark.t.sol"; + +/// @notice Tests used to benchmark {BatchLockup}. +/// @dev This contract creates a Markdown file with the gas usage of each function. +contract BatchLockup_Gas_Test is Benchmark_Test { + /*////////////////////////////////////////////////////////////////////////// + STATE VARIABLES + //////////////////////////////////////////////////////////////////////////*/ + + uint128 internal constant AMOUNT_PER_ITEM = 10e18; + uint8[5] internal batches = [5, 10, 20, 30, 50]; + uint8[5] internal counts = [24, 24, 24, 24, 12]; + + /*////////////////////////////////////////////////////////////////////////// + TEST FUNCTION + //////////////////////////////////////////////////////////////////////////*/ + + function testGas_Implementations() external { + // Set the file path. + benchmarkResultsFile = string.concat(benchmarkResults, "SablierV2BatchLockup.md"); + + // Create the file if it doesn't exist, otherwise overwrite it. + vm.writeFile({ + path: benchmarkResultsFile, + data: string.concat( + "# Benchmarks for BatchLockup\n\n", + "| Function | Lockup Type | Segments/Tranches | Batch Size | Gas Usage |\n", + "| --- | --- | --- | --- | --- |\n" + ) + }); + + for (uint256 i; i < batches.length; ++i) { + // Benchmark the batch create functions for Lockup Linear. + gasCreateWithDurationsLL(batches[i]); + gasCreateWithTimestampsLL(batches[i]); + + // Benchmark the batch create functions for Lockup Dynamic. + gasCreateWithDurationsLD({ batchSize: batches[i], segmentsCount: counts[i] }); + gasCreateWithTimestampsLD({ batchSize: batches[i], segmentsCount: counts[i] }); + + // Benchmark the batch create functions for Lockup Tranched. + gasCreateWithDurationsLT({ batchSize: batches[i], tranchesCount: counts[i] }); + gasCreateWithTimestampsLT({ batchSize: batches[i], tranchesCount: counts[i] }); + } + } + + /*////////////////////////////////////////////////////////////////////////// + GAS BENCHMARKS FOR BATCH FUNCTIONS + //////////////////////////////////////////////////////////////////////////*/ + + function gasCreateWithDurationsLD(uint256 batchSize, uint256 segmentsCount) internal { + LockupDynamic.CreateWithDurations memory createParams = defaults.createWithDurationsBrokerNullLD(); + createParams.totalAmount = uint128(AMOUNT_PER_ITEM * segmentsCount); + createParams.segments = _generateSegmentsWithDuration(segmentsCount); + BatchLockup.CreateWithDurationsLD[] memory params = BatchLockupBuilder.fillBatch(createParams, batchSize); + + uint256 initialGas = gasleft(); + batchLockup.createWithDurationsLD(lockupDynamic, dai, params); + string memory gasUsed = vm.toString(initialGas - gasleft()); + + contentToAppend = string.concat( + "| `createWithDurationsLD` | Lockup Dynamic |", + vm.toString(segmentsCount), + " |", + vm.toString(batchSize), + " | ", + gasUsed, + " |" + ); + + // Append the content to the file. + _appendToFile(benchmarkResultsFile, contentToAppend); + } + + function gasCreateWithTimestampsLD(uint256 batchSize, uint256 segmentsCount) internal { + LockupDynamic.CreateWithTimestamps memory createParams = defaults.createWithTimestampsBrokerNullLD(); + createParams.startTime = getBlockTimestamp(); + createParams.totalAmount = uint128(AMOUNT_PER_ITEM * segmentsCount); + createParams.segments = _generateSegments(segmentsCount); + BatchLockup.CreateWithTimestampsLD[] memory params = BatchLockupBuilder.fillBatch(createParams, batchSize); + + uint256 initialGas = gasleft(); + batchLockup.createWithTimestampsLD(lockupDynamic, dai, params); + string memory gasUsed = vm.toString(initialGas - gasleft()); + + contentToAppend = string.concat( + "| `createWithTimestampsLD` | Lockup Dynamic |", + vm.toString(segmentsCount), + " |", + vm.toString(batchSize), + " | ", + gasUsed, + " |" + ); + + // Append the data to the file + _appendToFile(benchmarkResultsFile, contentToAppend); + } + + function gasCreateWithDurationsLL(uint256 batchSize) internal { + BatchLockup.CreateWithDurationsLL[] memory params = + BatchLockupBuilder.fillBatch({ params: defaults.createWithDurationsBrokerNullLL(), batchSize: batchSize }); + + uint256 initialGas = gasleft(); + batchLockup.createWithDurationsLL(lockupLinear, dai, params); + string memory gasUsed = vm.toString(initialGas - gasleft()); + + contentToAppend = string.concat( + "| `createWithDurationsLL` | Lockup Linear | N/A |", vm.toString(batchSize), " | ", gasUsed, " |" + ); + + // Append the content to the file. + _appendToFile(benchmarkResultsFile, contentToAppend); + } + + function gasCreateWithTimestampsLL(uint256 batchSize) internal { + BatchLockup.CreateWithTimestampsLL[] memory params = + BatchLockupBuilder.fillBatch({ params: defaults.createWithTimestampsBrokerNullLL(), batchSize: batchSize }); + + uint256 initialGas = gasleft(); + batchLockup.createWithTimestampsLL(lockupLinear, dai, params); + string memory gasUsed = vm.toString(initialGas - gasleft()); + + contentToAppend = string.concat( + "| `createWithTimestampsLL` | Lockup Linear | N/A |", vm.toString(batchSize), " | ", gasUsed, " |" + ); + + // Append the data to the file + _appendToFile(benchmarkResultsFile, contentToAppend); + } + + function gasCreateWithDurationsLT(uint256 batchSize, uint256 tranchesCount) internal { + LockupTranched.CreateWithDurations memory createParams = defaults.createWithDurationsBrokerNullLT(); + createParams.totalAmount = uint128(AMOUNT_PER_ITEM * tranchesCount); + createParams.tranches = _generateTranchesWithDuration(tranchesCount); + BatchLockup.CreateWithDurationsLT[] memory params = BatchLockupBuilder.fillBatch(createParams, batchSize); + + uint256 initialGas = gasleft(); + batchLockup.createWithDurationsLT(lockupTranched, dai, params); + string memory gasUsed = vm.toString(initialGas - gasleft()); + + contentToAppend = string.concat( + "| `createWithDurationsLT` | Lockup Tranched |", + vm.toString(tranchesCount), + " |", + vm.toString(batchSize), + " | ", + gasUsed, + " |" + ); + + // Append the content to the file. + _appendToFile(benchmarkResultsFile, contentToAppend); + } + + function gasCreateWithTimestampsLT(uint256 batchSize, uint256 tranchesCount) internal { + LockupTranched.CreateWithTimestamps memory createParams = defaults.createWithTimestampsBrokerNullLT(); + createParams.startTime = getBlockTimestamp(); + createParams.totalAmount = uint128(AMOUNT_PER_ITEM * tranchesCount); + createParams.tranches = _generateTranches(tranchesCount); + BatchLockup.CreateWithTimestampsLT[] memory params = BatchLockupBuilder.fillBatch(createParams, batchSize); + + uint256 initialGas = gasleft(); + batchLockup.createWithTimestampsLT(lockupTranched, dai, params); + string memory gasUsed = vm.toString(initialGas - gasleft()); + + contentToAppend = string.concat( + "| `createWithTimestampsLT` | Lockup Tranched |", + vm.toString(tranchesCount), + " |", + vm.toString(batchSize), + " | ", + gasUsed, + " |" + ); + + // Append the data to the file + _appendToFile(benchmarkResultsFile, contentToAppend); + } + + /*////////////////////////////////////////////////////////////////////////// + HELPERS + //////////////////////////////////////////////////////////////////////////*/ + + function _generateSegments(uint256 segmentsCount) private view returns (LockupDynamic.Segment[] memory) { + LockupDynamic.Segment[] memory segments = new LockupDynamic.Segment[](segmentsCount); + + // Populate segments. + for (uint256 i = 0; i < segmentsCount; ++i) { + segments[i] = LockupDynamic.Segment({ + amount: AMOUNT_PER_ITEM, + exponent: ud2x18(0.5e18), + timestamp: getBlockTimestamp() + uint40(defaults.CLIFF_DURATION() * (1 + i)) + }); + } + + return segments; + } + + function _generateSegmentsWithDuration(uint256 segmentsCount) + private + view + returns (LockupDynamic.SegmentWithDuration[] memory) + { + LockupDynamic.SegmentWithDuration[] memory segments = new LockupDynamic.SegmentWithDuration[](segmentsCount); + + // Populate segments. + for (uint256 i; i < segmentsCount; ++i) { + segments[i] = LockupDynamic.SegmentWithDuration({ + amount: AMOUNT_PER_ITEM, + exponent: ud2x18(0.5e18), + duration: defaults.CLIFF_DURATION() + }); + } + + return segments; + } + + function _generateTranches(uint256 tranchesCount) private view returns (LockupTranched.Tranche[] memory) { + LockupTranched.Tranche[] memory tranches = new LockupTranched.Tranche[](tranchesCount); + + // Populate tranches. + for (uint256 i = 0; i < tranchesCount; ++i) { + tranches[i] = ( + LockupTranched.Tranche({ + amount: AMOUNT_PER_ITEM, + timestamp: getBlockTimestamp() + uint40(defaults.CLIFF_DURATION() * (1 + i)) + }) + ); + } + + return tranches; + } + + function _generateTranchesWithDuration(uint256 tranchesCount) + private + view + returns (LockupTranched.TrancheWithDuration[] memory) + { + LockupTranched.TrancheWithDuration[] memory tranches = new LockupTranched.TrancheWithDuration[](tranchesCount); + + // Populate tranches. + for (uint256 i; i < tranchesCount; ++i) { + tranches[i] = + LockupTranched.TrancheWithDuration({ amount: AMOUNT_PER_ITEM, duration: defaults.CLIFF_DURATION() }); + } + + return tranches; + } +} diff --git a/benchmark/Benchmark.t.sol b/benchmark/Benchmark.t.sol index 78856032f..b2aaa3afe 100644 --- a/benchmark/Benchmark.t.sol +++ b/benchmark/Benchmark.t.sol @@ -2,8 +2,8 @@ pragma solidity >=0.8.22; import { UD60x18, ud } from "@prb/math/src/UD60x18.sol"; -import { ISablierV2Lockup } from "../src/interfaces/ISablierV2Lockup.sol"; +import { ISablierV2Lockup } from "../src/core/interfaces/ISablierV2Lockup.sol"; import { Base_Test } from "../test/Base.t.sol"; /// @notice Benchmark contract with common logic needed by all tests. @@ -32,7 +32,7 @@ abstract contract Benchmark_Test is Base_Test { //////////////////////////////////////////////////////////////////////////*/ function setUp() public virtual override { - super.setUp(); + Base_Test.setUp(); deal({ token: address(dai), to: users.sender, give: type(uint256).max }); resetPrank({ msgSender: users.sender }); @@ -47,11 +47,11 @@ abstract contract Benchmark_Test is Base_Test { function gasBurn() internal { // Set the caller to the Recipient for `burn` and change timestamp to the end time. - resetPrank({ msgSender: users.recipient }); + resetPrank({ msgSender: users.recipient0 }); vm.warp({ newTimestamp: defaults.END_TIME() }); - lockup.withdrawMax(streamIds[0], users.recipient); + lockup.withdrawMax(streamIds[0], users.recipient0); uint256 initialGas = gasleft(); lockup.burn(streamIds[0]); @@ -101,7 +101,7 @@ abstract contract Benchmark_Test is Base_Test { string memory gasUsed = vm.toString(initialGas - gasleft()); // Check if caller is recipient or not. - bool isCallerRecipient = caller == users.recipient; + bool isCallerRecipient = caller == users.recipient0; string memory s = isCallerRecipient ? string.concat("| `withdraw` ", extraInfo, " (by Recipient) | ") @@ -138,13 +138,13 @@ abstract contract Benchmark_Test is Base_Test { } function gasWithdraw_ByAnyone(uint256 streamId1, uint256 streamId2, string memory extraInfo) internal { - gasWithdraw_AfterEndTime(streamId1, users.sender, users.recipient, extraInfo); - gasWithdraw_BeforeEndTime(streamId2, users.sender, users.recipient, extraInfo); + gasWithdraw_AfterEndTime(streamId1, users.sender, users.recipient0, extraInfo); + gasWithdraw_BeforeEndTime(streamId2, users.sender, users.recipient0, extraInfo); } function gasWithdraw_ByRecipient(uint256 streamId1, uint256 streamId2, string memory extraInfo) internal { - gasWithdraw_AfterEndTime(streamId1, users.recipient, users.alice, extraInfo); - gasWithdraw_BeforeEndTime(streamId2, users.recipient, users.alice, extraInfo); + gasWithdraw_AfterEndTime(streamId1, users.recipient0, users.alice, extraInfo); + gasWithdraw_BeforeEndTime(streamId2, users.recipient0, users.alice, extraInfo); } /*////////////////////////////////////////////////////////////////////////// diff --git a/benchmark/LockupDynamic.Gas.t.sol b/benchmark/LockupDynamic.Gas.t.sol index afac9403d..a1945265c 100644 --- a/benchmark/LockupDynamic.Gas.t.sol +++ b/benchmark/LockupDynamic.Gas.t.sol @@ -4,7 +4,8 @@ pragma solidity >=0.8.22; import { ud2x18 } from "@prb/math/src/UD2x18.sol"; import { UD60x18, ud } from "@prb/math/src/UD60x18.sol"; -import { Broker, LockupDynamic } from "../src/types/DataTypes.sol"; +import { Broker, LockupDynamic } from "../src/core/types/DataTypes.sol"; + import { Benchmark_Test } from "./Benchmark.t.sol"; /// @notice Tests used to benchmark LockupDynamic. @@ -21,7 +22,7 @@ contract LockupDynamic_Gas_Test is Benchmark_Test { SET-UP FUNCTION //////////////////////////////////////////////////////////////////////////*/ function setUp() public override { - super.setUp(); + Benchmark_Test.setUp(); lockup = lockupDynamic; } @@ -170,7 +171,7 @@ contract LockupDynamic_Gas_Test is Benchmark_Test { ) private view - returns (LockupDynamic.CreateWithDurations memory) + returns (LockupDynamic.CreateWithDurations memory params) { LockupDynamic.SegmentWithDuration[] memory segments_ = new LockupDynamic.SegmentWithDuration[](totalSegments); @@ -187,16 +188,11 @@ contract LockupDynamic_Gas_Test is Benchmark_Test { uint128 depositAmount = AMOUNT_PER_SEGMENT * totalSegments; - return LockupDynamic.CreateWithDurations({ - sender: users.sender, - recipient: users.recipient, - totalAmount: _calculateTotalAmount(depositAmount, brokerFee), - asset: dai, - cancelable: true, - transferable: true, - segments: segments_, - broker: Broker({ account: users.broker, fee: brokerFee }) - }); + params = defaults.createWithDurationsLD(); + params.totalAmount = _calculateTotalAmount(depositAmount, brokerFee); + params.segments = segments_; + params.broker.fee = brokerFee; + return params; } function _createWithTimestampParams( @@ -205,7 +201,7 @@ contract LockupDynamic_Gas_Test is Benchmark_Test { ) private view - returns (LockupDynamic.CreateWithTimestamps memory) + returns (LockupDynamic.CreateWithTimestamps memory params) { LockupDynamic.Segment[] memory segments_ = new LockupDynamic.Segment[](totalSegments); @@ -222,16 +218,11 @@ contract LockupDynamic_Gas_Test is Benchmark_Test { uint128 depositAmount = AMOUNT_PER_SEGMENT * totalSegments; - return LockupDynamic.CreateWithTimestamps({ - sender: users.sender, - recipient: users.recipient, - totalAmount: _calculateTotalAmount(depositAmount, brokerFee), - asset: dai, - cancelable: true, - transferable: true, - startTime: getBlockTimestamp(), - segments: segments_, - broker: Broker({ account: users.broker, fee: brokerFee }) - }); + params = defaults.createWithTimestampsLD(); + params.totalAmount = _calculateTotalAmount(depositAmount, brokerFee); + params.segments = segments_; + params.startTime = getBlockTimestamp(); + params.broker.fee = brokerFee; + return params; } } diff --git a/benchmark/LockupLinear.Gas.t.sol b/benchmark/LockupLinear.Gas.t.sol index f4d35e961..617d97f7c 100644 --- a/benchmark/LockupLinear.Gas.t.sol +++ b/benchmark/LockupLinear.Gas.t.sol @@ -3,7 +3,7 @@ pragma solidity >=0.8.22; import { ud } from "@prb/math/src/UD60x18.sol"; -import { LockupLinear } from "../src/types/DataTypes.sol"; +import { LockupLinear } from "../src/core/types/DataTypes.sol"; import { Benchmark_Test } from "./Benchmark.t.sol"; @@ -15,7 +15,7 @@ contract LockupLinear_Gas_Test is Benchmark_Test { //////////////////////////////////////////////////////////////////////////*/ function setUp() public override { - super.setUp(); + Benchmark_Test.setUp(); lockup = lockupLinear; } diff --git a/benchmark/LockupTranched.Gas.t.sol b/benchmark/LockupTranched.Gas.t.sol index 591e80c89..bdb6cdd7f 100644 --- a/benchmark/LockupTranched.Gas.t.sol +++ b/benchmark/LockupTranched.Gas.t.sol @@ -3,7 +3,7 @@ pragma solidity >=0.8.22; import { UD60x18, ud } from "@prb/math/src/UD60x18.sol"; -import { Broker, LockupTranched } from "../src/types/DataTypes.sol"; +import { Broker, LockupTranched } from "../src/core/types/DataTypes.sol"; import { Benchmark_Test } from "./Benchmark.t.sol"; @@ -22,7 +22,7 @@ contract LockupTranched_Gas_Test is Benchmark_Test { //////////////////////////////////////////////////////////////////////////*/ function setUp() public override { - super.setUp(); + Benchmark_Test.setUp(); lockup = lockupTranched; } @@ -167,7 +167,7 @@ contract LockupTranched_Gas_Test is Benchmark_Test { ) private view - returns (LockupTranched.CreateWithDurations memory) + returns (LockupTranched.CreateWithDurations memory params) { LockupTranched.TrancheWithDuration[] memory tranches_ = new LockupTranched.TrancheWithDuration[](totalTranches); @@ -180,16 +180,11 @@ contract LockupTranched_Gas_Test is Benchmark_Test { uint128 depositAmount = AMOUNT_PER_SEGMENT * totalTranches; - return LockupTranched.CreateWithDurations({ - sender: users.sender, - recipient: users.recipient, - totalAmount: _calculateTotalAmount(depositAmount, brokerFee), - asset: dai, - cancelable: true, - transferable: true, - tranches: tranches_, - broker: Broker({ account: users.broker, fee: brokerFee }) - }); + params = defaults.createWithDurationsLT(); + params.broker.fee = brokerFee; + params.totalAmount = _calculateTotalAmount(depositAmount, brokerFee); + params.tranches = tranches_; + return params; } function _createWithTimestampParams( @@ -198,7 +193,7 @@ contract LockupTranched_Gas_Test is Benchmark_Test { ) private view - returns (LockupTranched.CreateWithTimestamps memory) + returns (LockupTranched.CreateWithTimestamps memory params) { LockupTranched.Tranche[] memory tranches_ = new LockupTranched.Tranche[](totalTranches); @@ -214,16 +209,11 @@ contract LockupTranched_Gas_Test is Benchmark_Test { uint128 depositAmount = AMOUNT_PER_SEGMENT * totalTranches; - return LockupTranched.CreateWithTimestamps({ - sender: users.sender, - recipient: users.recipient, - totalAmount: _calculateTotalAmount(depositAmount, brokerFee), - asset: dai, - cancelable: true, - transferable: true, - startTime: getBlockTimestamp(), - tranches: tranches_, - broker: Broker({ account: users.broker, fee: brokerFee }) - }); + params = defaults.createWithTimestampsLT(); + params.broker.fee = brokerFee; + params.startTime = getBlockTimestamp(); + params.totalAmount = _calculateTotalAmount(depositAmount, brokerFee); + params.tranches = tranches_; + return params; } } diff --git a/benchmark/results/SablierV2BatchLockup.md b/benchmark/results/SablierV2BatchLockup.md new file mode 100644 index 000000000..112175f33 --- /dev/null +++ b/benchmark/results/SablierV2BatchLockup.md @@ -0,0 +1,34 @@ +# Benchmarks for BatchLockup + +| Function | Lockup Type | Segments/Tranches | Batch Size | Gas Usage | +| ------------------------ | --------------- | ----------------- | ---------- | --------- | +| `createWithDurationsLL` | Lockup Linear | N/A | 5 | 770796 | +| `createWithTimestampsLL` | Lockup Linear | N/A | 5 | 730532 | +| `createWithDurationsLD` | Lockup Dynamic | 24 | 5 | 3935335 | +| `createWithTimestampsLD` | Lockup Dynamic | 24 | 5 | 3797841 | +| `createWithDurationsLT` | Lockup Tranched | 24 | 5 | 3844973 | +| `createWithTimestampsLT` | Lockup Tranched | 24 | 5 | 3726799 | +| `createWithDurationsLL` | Lockup Linear | N/A | 10 | 1413200 | +| `createWithTimestampsLL` | Lockup Linear | N/A | 10 | 1410133 | +| `createWithDurationsLD` | Lockup Dynamic | 24 | 10 | 7785667 | +| `createWithTimestampsLD` | Lockup Dynamic | 24 | 10 | 7547946 | +| `createWithDurationsLT` | Lockup Tranched | 24 | 10 | 7596904 | +| `createWithTimestampsLT` | Lockup Tranched | 24 | 10 | 7406060 | +| `createWithDurationsLL` | Lockup Linear | N/A | 20 | 2775981 | +| `createWithTimestampsLL` | Lockup Linear | N/A | 20 | 2771033 | +| `createWithDurationsLD` | Lockup Dynamic | 24 | 20 | 15547587 | +| `createWithTimestampsLD` | Lockup Dynamic | 24 | 20 | 15056228 | +| `createWithDurationsLT` | Lockup Tranched | 24 | 20 | 15143062 | +| `createWithTimestampsLT` | Lockup Tranched | 24 | 20 | 14770870 | +| `createWithDurationsLL` | Lockup Linear | N/A | 30 | 4133268 | +| `createWithTimestampsLL` | Lockup Linear | N/A | 30 | 4136198 | +| `createWithDurationsLD` | Lockup Dynamic | 24 | 30 | 23351853 | +| `createWithTimestampsLD` | Lockup Dynamic | 24 | 30 | 22583299 | +| `createWithDurationsLT` | Lockup Tranched | 24 | 30 | 22691758 | +| `createWithTimestampsLT` | Lockup Tranched | 24 | 30 | 22152793 | +| `createWithDurationsLL` | Lockup Linear | N/A | 50 | 6854756 | +| `createWithTimestampsLL` | Lockup Linear | N/A | 50 | 6872537 | +| `createWithDurationsLD` | Lockup Dynamic | 12 | 50 | 22883512 | +| `createWithTimestampsLD` | Lockup Dynamic | 12 | 50 | 22241640 | +| `createWithDurationsLT` | Lockup Tranched | 12 | 50 | 22314003 | +| `createWithTimestampsLT` | Lockup Tranched | 12 | 50 | 21891398 | diff --git a/benchmark/results/SablierV2LockupDynamic.md b/benchmark/results/SablierV2LockupDynamic.md index de8e2145b..7ca0a2fcd 100644 --- a/benchmark/results/SablierV2LockupDynamic.md +++ b/benchmark/results/SablierV2LockupDynamic.md @@ -4,27 +4,27 @@ | ---------------------------------------------------------- | --------- | | `burn` | 15716 | | `cancel` | 74341 | -| `renounce` | 39007 | -| `createWithDurations` (2 segments) (Broker fee set) | 200602 | -| `createWithDurations` (2 segments) (Broker fee not set) | 185037 | -| `createWithTimestamps` (2 segments) (Broker fee set) | 184780 | -| `createWithTimestamps` (2 segments) (Broker fee not set) | 180015 | -| `withdraw` (2 segments) (After End Time) (by Recipient) | 19108 | +| `renounce` | 39001 | +| `createWithDurations` (2 segments) (Broker fee set) | 200605 | +| `createWithDurations` (2 segments) (Broker fee not set) | 185039 | +| `createWithTimestamps` (2 segments) (Broker fee set) | 184785 | +| `createWithTimestamps` (2 segments) (Broker fee not set) | 180023 | +| `withdraw` (2 segments) (After End Time) (by Recipient) | 19109 | | `withdraw` (2 segments) (Before End Time) (by Recipient) | 27554 | -| `withdraw` (2 segments) (After End Time) (by Anyone) | 14239 | +| `withdraw` (2 segments) (After End Time) (by Anyone) | 14241 | | `withdraw` (2 segments) (Before End Time) (by Anyone) | 27485 | -| `createWithDurations` (10 segments) (Broker fee set) | 395084 | -| `createWithDurations` (10 segments) (Broker fee not set) | 390326 | -| `createWithTimestamps` (10 segments) (Broker fee set) | 385125 | -| `createWithTimestamps` (10 segments) (Broker fee not set) | 380375 | +| `createWithDurations` (10 segments) (Broker fee set) | 395105 | +| `createWithDurations` (10 segments) (Broker fee not set) | 390350 | +| `createWithTimestamps` (10 segments) (Broker fee set) | 385155 | +| `createWithTimestamps` (10 segments) (Broker fee not set) | 380410 | | `withdraw` (10 segments) (After End Time) (by Recipient) | 14295 | | `withdraw` (10 segments) (Before End Time) (by Recipient) | 32545 | -| `withdraw` (10 segments) (After End Time) (by Anyone) | 14246 | +| `withdraw` (10 segments) (After End Time) (by Anyone) | 14249 | | `withdraw` (10 segments) (Before End Time) (by Anyone) | 32476 | -| `createWithDurations` (100 segments) (Broker fee set) | 2740781 | -| `createWithDurations` (100 segments) (Broker fee not set) | 2736987 | -| `createWithTimestamps` (100 segments) (Broker fee set) | 2642946 | -| `createWithTimestamps` (100 segments) (Broker fee not set) | 2639185 | +| `createWithDurations` (100 segments) (Broker fee set) | 2741072 | +| `createWithDurations` (100 segments) (Broker fee not set) | 2737309 | +| `createWithTimestamps` (100 segments) (Broker fee set) | 2643302 | +| `createWithTimestamps` (100 segments) (Broker fee not set) | 2639574 | | `withdraw` (100 segments) (After End Time) (by Recipient) | 14295 | | `withdraw` (100 segments) (Before End Time) (by Recipient) | 88968 | | `withdraw` (100 segments) (After End Time) (by Anyone) | 14226 | diff --git a/benchmark/results/SablierV2LockupLinear.md b/benchmark/results/SablierV2LockupLinear.md index d53fa08f9..32085722d 100644 --- a/benchmark/results/SablierV2LockupLinear.md +++ b/benchmark/results/SablierV2LockupLinear.md @@ -3,17 +3,17 @@ | Implementation | Gas Usage | | ----------------------------------------------------------- | --------- | | `burn` | 15694 | -| `cancel` | 56829 | -| `renounce` | 19381 | +| `cancel` | 56832 | +| `renounce` | 19378 | | `createWithDurations` (Broker fee set) (cliff not set) | 129276 | | `createWithDurations` (Broker fee not set) (cliff not set) | 113680 | | `createWithDurations` (Broker fee set) (cliff set) | 138071 | -| `createWithDurations` (Broker fee not set) (cliff set) | 133273 | +| `createWithDurations` (Broker fee not set) (cliff set) | 133274 | | `createWithTimestamps` (Broker fee set) (cliff not set) | 115334 | | `createWithTimestamps` (Broker fee not set) (cliff not set) | 110530 | | `createWithTimestamps` (Broker fee set) (cliff set) | 137629 | | `createWithTimestamps` (Broker fee not set) (cliff set) | 132827 | -| `withdraw` (After End Time) (by Recipient) | 29701 | -| `withdraw` (Before End Time) (by Recipient) | 19104 | -| `withdraw` (After End Time) (by Anyone) | 24799 | -| `withdraw` (Before End Time) (by Anyone) | 19002 | +| `withdraw` (After End Time) (by Recipient) | 29704 | +| `withdraw` (Before End Time) (by Recipient) | 19107 | +| `withdraw` (After End Time) (by Anyone) | 24802 | +| `withdraw` (Before End Time) (by Anyone) | 19005 | diff --git a/benchmark/results/SablierV2LockupTranched.md b/benchmark/results/SablierV2LockupTranched.md index ec7ea9494..edb9330a8 100644 --- a/benchmark/results/SablierV2LockupTranched.md +++ b/benchmark/results/SablierV2LockupTranched.md @@ -4,27 +4,27 @@ | ---------------------------------------------------------- | --------- | | `burn` | 15738 | | `cancel` | 63994 | -| `renounce` | 26501 | -| `createWithDurations` (2 tranches) (Broker fee set) | 199536 | -| `createWithDurations` (2 tranches) (Broker fee not set) | 183969 | -| `createWithTimestamps` (2 tranches) (Broker fee set) | 189410 | -| `createWithTimestamps` (2 tranches) (Broker fee not set) | 183945 | -| `withdraw` (2 tranches) (After End Time) (by Recipient) | 20100 | +| `renounce` | 26495 | +| `createWithDurations` (2 tranches) (Broker fee set) | 199538 | +| `createWithDurations` (2 tranches) (Broker fee not set) | 183973 | +| `createWithTimestamps` (2 tranches) (Broker fee set) | 195734 | +| `createWithTimestamps` (2 tranches) (Broker fee not set) | 190260 | +| `withdraw` (2 tranches) (After End Time) (by Recipient) | 20102 | | `withdraw` (2 tranches) (Before End Time) (by Recipient) | 14797 | -| `withdraw` (2 tranches) (After End Time) (by Anyone) | 15199 | +| `withdraw` (2 tranches) (After End Time) (by Anyone) | 15201 | | `withdraw` (2 tranches) (Before End Time) (by Anyone) | 14695 | -| `createWithDurations` (10 tranches) (Broker fee set) | 388757 | -| `createWithDurations` (10 tranches) (Broker fee not set) | 383998 | -| `createWithTimestamps` (10 tranches) (Broker fee set) | 397102 | -| `createWithTimestamps` (10 tranches) (Broker fee not set) | 391750 | -| `withdraw` (10 tranches) (After End Time) (by Recipient) | 17855 | +| `createWithDurations` (10 tranches) (Broker fee set) | 388774 | +| `createWithDurations` (10 tranches) (Broker fee not set) | 384017 | +| `createWithTimestamps` (10 tranches) (Broker fee set) | 403722 | +| `createWithTimestamps` (10 tranches) (Broker fee not set) | 398385 | +| `withdraw` (10 tranches) (After End Time) (by Recipient) | 17857 | | `withdraw` (10 tranches) (Before End Time) (by Recipient) | 19616 | -| `withdraw` (10 tranches) (After End Time) (by Anyone) | 17760 | +| `withdraw` (10 tranches) (After End Time) (by Anyone) | 17763 | | `withdraw` (10 tranches) (Before End Time) (by Anyone) | 19514 | -| `createWithDurations` (100 tranches) (Broker fee set) | 2672918 | -| `createWithDurations` (100 tranches) (Broker fee not set) | 2668643 | -| `createWithTimestamps` (100 tranches) (Broker fee set) | 2738297 | -| `createWithTimestamps` (100 tranches) (Broker fee not set) | 2734635 | +| `createWithDurations` (100 tranches) (Broker fee set) | 2673124 | +| `createWithDurations` (100 tranches) (Broker fee not set) | 2668870 | +| `createWithTimestamps` (100 tranches) (Broker fee set) | 2747871 | +| `createWithTimestamps` (100 tranches) (Broker fee not set) | 2744348 | | `withdraw` (100 tranches) (After End Time) (by Recipient) | 46746 | | `withdraw` (100 tranches) (Before End Time) (by Recipient) | 73989 | | `withdraw` (100 tranches) (After End Time) (by Anyone) | 46644 | diff --git a/shell/deploy-multi-chain.sh b/shell/deploy-multi-chain.sh index 973844e13..a0414ff07 100755 --- a/shell/deploy-multi-chain.sh +++ b/shell/deploy-multi-chain.sh @@ -288,7 +288,7 @@ for chain in "${provided_chains[@]}"; do if [[ ${DETERMINISTIC_DEPLOYMENT} == true ]]; then echo -e "${SC}+${NC} Deterministic address" if [[ ${sol_script} == "" ]]; then - deployment_command+=("script" "script/DeployDeterministicCore.s.sol") + deployment_command+=("script" "script/DeployDeterministicProtocol.s.sol") else deployment_command+=("script" "${sol_script}") fi @@ -307,7 +307,7 @@ for chain in "${provided_chains[@]}"; do else # Construct the command if [[ ${sol_script} == "" ]]; then - deployment_command+=("script" "script/DeployCore.s.sol") + deployment_command+=("script" "script/DeployProtocol.s.sol") else deployment_command+=("script" "${sol_script}") fi @@ -356,17 +356,23 @@ for chain in "${provided_chains[@]}"; do touch "${chain_file}" # Extract and save contract addresses + batchLockup_address=$(echo "${output}" | awk '/batchLockup: contract/{print $NF}') lockupDynamic_address=$(echo "${output}" | awk '/lockupDynamic: contract/{print $NF}') lockupLinear_address=$(echo "${output}" | awk '/lockupLinear: contract/{print $NF}') lockupTranched_address=$(echo "${output}" | awk '/lockupTranched: contract/{print $NF}') + merkleLockupFactory_address=$(echo "${output}" | awk '/merkleLockupFactory: contract/{print $NF}') nftDescriptor_address=$(echo "${output}" | awk '/nftDescriptor: contract/{print $NF}') # Save to the chain file { + echo "Core Contracts" echo "SablierV2LockupDynamic = ${lockupDynamic_address}" echo "SablierV2LockupLinear = ${lockupLinear_address}" echo "SablierV2LockupTranched = ${lockupTranched_address}" echo "SablierV2NFTDescriptor = ${nftDescriptor_address}" + echo "Periphery Contracts" + echo "SablierV2BatchLockup = ${batchLockup_address}" + echo "SablierV2MerkleLockupFactory = ${merkleLockupFactory_address}" } >> "$chain_file" echo -e "${SC}${TICK} Deployed on ${chain}. You can find the addresses in ${chain_file}${NC}" diff --git a/shell/prepare-artifacts.sh b/shell/prepare-artifacts.sh index 5aa4f6ab5..e696f46db 100755 --- a/shell/prepare-artifacts.sh +++ b/shell/prepare-artifacts.sh @@ -7,43 +7,74 @@ # Strict mode: https://gist.github.com/vncsna/64825d5609c146e80de8b1fd623011ca set -euo pipefail +# Generate the artifacts with Forge +FOUNDRY_PROFILE=optimized forge build + # Delete the current artifacts artifacts=./artifacts rm -rf $artifacts # Create the new artifacts directories mkdir $artifacts \ - "$artifacts/interfaces" \ - "$artifacts/interfaces/erc20" \ - "$artifacts/interfaces/erc721" \ - "$artifacts/libraries" + "$artifacts/core" \ + "$artifacts/core/interfaces" \ + "$artifacts/core/libraries" \ + "$artifacts/erc20" \ + "$artifacts/erc721" \ + "$artifacts/periphery" \ + "$artifacts/periphery/interfaces" \ + "$artifacts/periphery/libraries" -# Generate the artifacts with Forge -FOUNDRY_PROFILE=optimized forge build +################################################ +#### CORE #### +################################################ + +core=./artifacts/core +cp out-optimized/SablierV2LockupDynamic.sol/SablierV2LockupDynamic.json $core +cp out-optimized/SablierV2LockupLinear.sol/SablierV2LockupLinear.json $core +cp out-optimized/SablierV2LockupTranched.sol/SablierV2LockupTranched.json $core +cp out-optimized/SablierV2NFTDescriptor.sol/SablierV2NFTDescriptor.json $core + +core_interfaces=./artifacts/core/interfaces +cp out-optimized/ISablierLockupRecipient.sol/ISablierLockupRecipient.json $core_interfaces +cp out-optimized/ISablierV2Lockup.sol/ISablierV2Lockup.json $core_interfaces +cp out-optimized/ISablierV2LockupDynamic.sol/ISablierV2LockupDynamic.json $core_interfaces +cp out-optimized/ISablierV2LockupLinear.sol/ISablierV2LockupLinear.json $core_interfaces +cp out-optimized/ISablierV2LockupTranched.sol/ISablierV2LockupTranched.json $core_interfaces +cp out-optimized/ISablierV2NFTDescriptor.sol/ISablierV2NFTDescriptor.json $core_interfaces -# Copy the production artifacts -cp out-optimized/SablierV2LockupDynamic.sol/SablierV2LockupDynamic.json $artifacts -cp out-optimized/SablierV2LockupLinear.sol/SablierV2LockupLinear.json $artifacts -cp out-optimized/SablierV2LockupTranched.sol/SablierV2LockupTranched.json $artifacts -cp out-optimized/SablierV2NFTDescriptor.sol/SablierV2NFTDescriptor.json $artifacts - -interfaces=./artifacts/interfaces -cp out-optimized/ISablierLockupRecipient.sol/ISablierLockupRecipient.json $interfaces -cp out-optimized/ISablierV2Lockup.sol/ISablierV2Lockup.json $interfaces -cp out-optimized/ISablierV2LockupDynamic.sol/ISablierV2LockupDynamic.json $interfaces -cp out-optimized/ISablierV2LockupLinear.sol/ISablierV2LockupLinear.json $interfaces -cp out-optimized/ISablierV2LockupTranched.sol/ISablierV2LockupTranched.json $interfaces -cp out-optimized/ISablierV2NFTDescriptor.sol/ISablierV2NFTDescriptor.json $interfaces - -erc20=./artifacts/interfaces/erc20 +core_libraries=./artifacts/core/libraries +cp out-optimized/Errors.sol/Errors.json $core_libraries + +################################################ +#### PERIPHERY #### +################################################ + +periphery=./artifacts/periphery +cp out-optimized/SablierV2BatchLockup.sol/SablierV2BatchLockup.json $periphery +cp out-optimized/SablierV2MerkleLL.sol/SablierV2MerkleLL.json $periphery +cp out-optimized/SablierV2MerkleLockupFactory.sol/SablierV2MerkleLockupFactory.json $periphery +cp out-optimized/SablierV2MerkleLT.sol/SablierV2MerkleLT.json $periphery + +periphery_interfaces=./artifacts/periphery/interfaces +cp out-optimized/ISablierV2BatchLockup.sol/ISablierV2BatchLockup.json $periphery_interfaces +cp out-optimized/ISablierV2MerkleLL.sol/ISablierV2MerkleLL.json $periphery_interfaces +cp out-optimized/ISablierV2MerkleLockupFactory.sol/ISablierV2MerkleLockupFactory.json $periphery_interfaces +cp out-optimized/ISablierV2MerkleLT.sol/ISablierV2MerkleLT.json $periphery_interfaces + +periphery_libraries=./artifacts/periphery/libraries +cp out-optimized/libraries/Errors.sol/Errors.json $periphery_libraries + +################################################ +#### OTHERS #### +################################################ + +erc20=./artifacts/erc20 cp out-optimized/IERC20.sol/IERC20.json $erc20 -erc721=./artifacts/interfaces/erc721 +erc721=./artifacts/erc721 cp out-optimized/IERC721.sol/IERC721.json $erc721 cp out-optimized/IERC721Metadata.sol/IERC721Metadata.json $erc721 -libraries=./artifacts/libraries -cp out-optimized/Errors.sol/Errors.json $libraries - # Format the artifacts with Prettier bun prettier --write ./artifacts