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

feat: add SablierMerkleInstant #999

Merged
merged 6 commits into from
Aug 12, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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
29 changes: 12 additions & 17 deletions precompiles/Precompiles.sol

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions script/DeployDeterministicProtocol.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { LockupNFTDescriptor } from "../src/core/LockupNFTDescriptor.sol";
import { SablierLockupDynamic } from "../src/core/SablierLockupDynamic.sol";
import { SablierLockupLinear } from "../src/core/SablierLockupLinear.sol";
import { SablierLockupTranched } from "../src/core/SablierLockupTranched.sol";
import { SablierMerkleLockupFactory } from "../src/periphery/SablierMerkleLockupFactory.sol";
import { SablierMerkleFactory } from "../src/periphery/SablierMerkleFactory.sol";
import { SablierBatchLockup } from "../src/periphery/SablierBatchLockup.sol";

import { BaseScript } from "./Base.s.sol";
Expand All @@ -23,7 +23,7 @@ contract DeployDeterministicProtocol is BaseScript {
SablierLockupLinear lockupLinear,
SablierLockupTranched lockupTranched,
SablierBatchLockup batchLockup,
SablierMerkleLockupFactory merkleLockupFactory
SablierMerkleFactory merkleFactory
)
{
bytes32 salt = constructCreate2Salt();
Expand All @@ -38,6 +38,6 @@ contract DeployDeterministicProtocol is BaseScript {

// Deploy Periphery.
batchLockup = new SablierBatchLockup{ salt: salt }();
merkleLockupFactory = new SablierMerkleLockupFactory{ salt: salt }();
merkleFactory = new SablierMerkleFactory{ salt: salt }();
}
}
6 changes: 3 additions & 3 deletions script/DeployProtocol.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { LockupNFTDescriptor } from "../src/core/LockupNFTDescriptor.sol";
import { SablierLockupDynamic } from "../src/core/SablierLockupDynamic.sol";
import { SablierLockupLinear } from "../src/core/SablierLockupLinear.sol";
import { SablierLockupTranched } from "../src/core/SablierLockupTranched.sol";
import { SablierMerkleLockupFactory } from "../src/periphery/SablierMerkleLockupFactory.sol";
import { SablierMerkleFactory } from "../src/periphery/SablierMerkleFactory.sol";
import { SablierBatchLockup } from "../src/periphery/SablierBatchLockup.sol";

import { BaseScript } from "./Base.s.sol";
Expand All @@ -23,7 +23,7 @@ contract DeployProtocol is BaseScript {
SablierLockupLinear lockupLinear,
SablierLockupTranched lockupTranched,
SablierBatchLockup batchLockup,
SablierMerkleLockupFactory merkleLockupFactory
SablierMerkleFactory merkleFactory
)
{
// Deploy Core.
Expand All @@ -34,6 +34,6 @@ contract DeployProtocol is BaseScript {

// Deploy Periphery.
batchLockup = new SablierBatchLockup();
merkleLockupFactory = new SablierMerkleLockupFactory();
merkleFactory = new SablierMerkleFactory();
}
}
33 changes: 33 additions & 0 deletions script/periphery/CreateMerkleInstant.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.8.22 <0.9.0;

import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

import { ISablierMerkleFactory } from "../../src/periphery/interfaces/ISablierMerkleFactory.sol";
import { ISablierMerkleInstant } from "../../src/periphery/interfaces/ISablierMerkleInstant.sol";
import { MerkleBase } from "../../src/periphery/types/DataTypes.sol";

import { BaseScript } from "../Base.s.sol";

contract CreateMerkleInstant is BaseScript {
/// @dev Deploy via Forge.
function run() public virtual broadcast returns (ISablierMerkleInstant merkleInstant) {
// Prepare the constructor parameters.
// TODO: Update address once deployed.
ISablierMerkleFactory merkleFactory = ISablierMerkleFactory(0xF35aB407CF28012Ba57CAF5ee2f6d6E4420253bc);

MerkleBase.ConstructorParams memory baseParams;
baseParams.asset = IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F);
baseParams.expiration = uint40(block.timestamp + 30 days);
baseParams.initialAdmin = 0x79Fb3e81aAc012c08501f41296CCC145a1E15844;
baseParams.ipfsCID = "QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR";
baseParams.merkleRoot = 0x0000000000000000000000000000000000000000000000000000000000000000;
baseParams.name = "The Boys Instant";

uint256 campaignTotalAmount = 10_000e18;
uint256 recipientCount = 100;

// Deploy MerkleInstant contract.
merkleInstant = merkleFactory.createMerkleInstant(baseParams, campaignTotalAmount, recipientCount);
}
}
33 changes: 15 additions & 18 deletions script/periphery/CreateMerkleLL.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,37 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

import { ISablierLockupLinear } from "../../src/core/interfaces/ISablierLockupLinear.sol";
import { LockupLinear } from "../../src/core/types/DataTypes.sol";
import { ISablierMerkleFactory } from "../../src/periphery/interfaces/ISablierMerkleFactory.sol";
import { ISablierMerkleLL } from "../../src/periphery/interfaces/ISablierMerkleLL.sol";
import { ISablierMerkleLockupFactory } from "../../src/periphery/interfaces/ISablierMerkleLockupFactory.sol";
import { MerkleLockup } from "../../src/periphery/types/DataTypes.sol";
import { MerkleBase } from "../../src/periphery/types/DataTypes.sol";

import { BaseScript } from "../Base.s.sol";

contract CreateMerkleLL is BaseScript {
/// @dev Deploy via Forge.
function run() public virtual broadcast returns (ISablierMerkleLL merkleLL) {
// Prepare the constructor parameters.
ISablierMerkleLockupFactory merkleLockupFactory =
ISablierMerkleLockupFactory(0xF35aB407CF28012Ba57CAF5ee2f6d6E4420253bc); // TODO: Update address once deployed.
// TODO: Update address once deployed.
ISablierMerkleFactory merkleFactory = ISablierMerkleFactory(0xF35aB407CF28012Ba57CAF5ee2f6d6E4420253bc);

MerkleLockup.ConstructorParams memory baseParams;
MerkleBase.ConstructorParams memory baseParams;
baseParams.asset = IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F);
baseParams.cancelable = true;
baseParams.expiration = uint40(block.timestamp + 30 days);
baseParams.initialAdmin = 0x79Fb3e81aAc012c08501f41296CCC145a1E15844;
baseParams.ipfsCID = "QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR";
baseParams.merkleRoot = 0x0000000000000000000000000000000000000000000000000000000000000000;
baseParams.name = "The Boys LL";
baseParams.transferable = true;

// TODO: Update address once deployed.
ISablierLockupLinear lockupLinear = ISablierLockupLinear(0x3962f6585946823440d274aD7C719B02b49DE51E);
LockupLinear.Durations memory streamDurations;
streamDurations.cliff = 0;
streamDurations.total = 3600;
uint256 campaignTotalAmount = 10_000e18;
uint256 recipientCount = 100;

// Deploy MerkleLL contract.
merkleLL = merkleLockupFactory.createMerkleLL(
baseParams, lockupLinear, streamDurations, campaignTotalAmount, recipientCount
);
// TODO: Update address once deployed.
merkleLL = merkleFactory.createMerkleLL({
baseParams: baseParams,
lockupLinear: ISablierLockupLinear(0x3962f6585946823440d274aD7C719B02b49DE51E),
cancelable: true,
transferable: true,
streamDurations: LockupLinear.Durations({ cliff: 0, total: 3600 }),
aggregateAmount: 10_000e18,
recipientCount: 100
});
}
}
29 changes: 15 additions & 14 deletions script/periphery/CreateMerkleLT.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,42 +5,43 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { UD2x18 } from "@prb/math/src/UD2x18.sol";

import { ISablierLockupTranched } from "../../src/core/interfaces/ISablierLockupTranched.sol";
import { ISablierMerkleLockupFactory } from "../../src/periphery/interfaces/ISablierMerkleLockupFactory.sol";
import { ISablierMerkleFactory } from "../../src/periphery/interfaces/ISablierMerkleFactory.sol";
import { ISablierMerkleLT } from "../../src/periphery/interfaces/ISablierMerkleLT.sol";
import { MerkleLockup, MerkleLT } from "../../src/periphery/types/DataTypes.sol";
import { MerkleBase, MerkleLT } from "../../src/periphery/types/DataTypes.sol";

import { BaseScript } from "../Base.s.sol";

contract CreateMerkleLT is BaseScript {
/// @dev Deploy via Forge.
function run() public virtual broadcast returns (ISablierMerkleLT merkleLT) {
// Prepare the constructor parameters.
ISablierMerkleLockupFactory merkleLockupFactory =
ISablierMerkleLockupFactory(0xF35aB407CF28012Ba57CAF5ee2f6d6E4420253bc); // TODO: Update address once deployed.
// TODO: Update address once deployed.
ISablierMerkleFactory merkleFactory = ISablierMerkleFactory(0xF35aB407CF28012Ba57CAF5ee2f6d6E4420253bc);

MerkleLockup.ConstructorParams memory baseParams;
MerkleBase.ConstructorParams memory baseParams;
baseParams.asset = IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F);
baseParams.cancelable = true;
baseParams.expiration = uint40(block.timestamp + 30 days);
baseParams.initialAdmin = 0x79Fb3e81aAc012c08501f41296CCC145a1E15844;
baseParams.ipfsCID = "QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR";
baseParams.merkleRoot = 0x0000000000000000000000000000000000000000000000000000000000000000;
baseParams.name = "The Boys LT";
baseParams.transferable = true;

// TODO: Update address once deployed.
ISablierLockupTranched lockupTranched = ISablierLockupTranched(0xf86B359035208e4529686A1825F2D5BeE38c28A8);
MerkleLT.TrancheWithPercentage[] memory tranchesWithPercentages = new MerkleLT.TrancheWithPercentage[](2);
tranchesWithPercentages[0] =
MerkleLT.TrancheWithPercentage({ unlockPercentage: UD2x18.wrap(50), duration: 3600 });
tranchesWithPercentages[1] =
MerkleLT.TrancheWithPercentage({ unlockPercentage: UD2x18.wrap(50), duration: 7200 });
uint256 campaignTotalAmount = 10_000e18;
uint256 recipientCount = 100;

// Deploy MerkleLT contract.
merkleLT = merkleLockupFactory.createMerkleLT(
baseParams, lockupTranched, tranchesWithPercentages, campaignTotalAmount, recipientCount
);
// TODO: Update address once deployed.
merkleLT = merkleFactory.createMerkleLT({
baseParams: baseParams,
lockupTranched: ISablierLockupTranched(0xf86B359035208e4529686A1825F2D5BeE38c28A8),
cancelable: true,
transferable: true,
tranchesWithPercentages: tranchesWithPercentages,
aggregateAmount: 10_000e18,
recipientCount: 100
});
}
}
8 changes: 4 additions & 4 deletions script/periphery/DeployDeterministicPeriphery.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
pragma solidity >=0.8.22 <0.9.0;

import { SablierBatchLockup } from "../../src/periphery/SablierBatchLockup.sol";
import { SablierMerkleLockupFactory } from "../../src/periphery/SablierMerkleLockupFactory.sol";
import { SablierMerkleFactory } from "../../src/periphery/SablierMerkleFactory.sol";

import { BaseScript } from "../Base.s.sol";

/// @notice Deploys all Periphery contracts at deterministic addresses across chains, in the following order:
///
/// 1. {SablierBatchLockup}
/// 2. {SablierMerkleLockupFactory}
/// 2. {SablierMerkleFactory}
///
/// @dev Reverts if any contract has already been deployed.
contract DeployDeterministicPeriphery is BaseScript {
Expand All @@ -18,10 +18,10 @@ contract DeployDeterministicPeriphery is BaseScript {
public
virtual
broadcast
returns (SablierBatchLockup batchLockup, SablierMerkleLockupFactory merkleLockupFactory)
returns (SablierBatchLockup batchLockup, SablierMerkleFactory merkleFactory)
{
bytes32 salt = constructCreate2Salt();
batchLockup = new SablierBatchLockup{ salt: salt }();
merkleLockupFactory = new SablierMerkleLockupFactory{ salt: salt }();
merkleFactory = new SablierMerkleFactory{ salt: salt }();
}
}
13 changes: 13 additions & 0 deletions script/periphery/DeployMerkleFactory.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.8.22 <0.9.0;

import { SablierMerkleFactory } from "../../src/periphery/SablierMerkleFactory.sol";

import { BaseScript } from "../Base.s.sol";

contract DeployMerkleFactory is BaseScript {
/// @dev Deploy via Forge.
function run() public virtual broadcast returns (SablierMerkleFactory merkleFactory) {
merkleFactory = new SablierMerkleFactory();
}
}
13 changes: 0 additions & 13 deletions script/periphery/DeployMerkleLockupFactory.s.sol
smol-ninja marked this conversation as resolved.
Outdated
Show resolved Hide resolved

This file was deleted.

8 changes: 4 additions & 4 deletions script/periphery/DeployPeriphery.s.sol
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.8.22 <0.9.0;

import { SablierMerkleLockupFactory } from "../../src/periphery/SablierMerkleLockupFactory.sol";
import { SablierMerkleFactory } from "../../src/periphery/SablierMerkleFactory.sol";
import { SablierBatchLockup } from "../../src/periphery/SablierBatchLockup.sol";

import { BaseScript } from "../Base.s.sol";

/// @notice Deploys all Periphery contract in the following order:
///
/// 1. {SablierBatchLockup}
/// 2. {SablierMerkleLockupFactory}
/// 2. {SablierMerkleFactory}
contract DeployPeriphery is BaseScript {
/// @dev Deploy via Forge.
function run()
public
virtual
broadcast
returns (SablierBatchLockup batchLockup, SablierMerkleLockupFactory merkleLockupFactory)
returns (SablierBatchLockup batchLockup, SablierMerkleFactory merkleFactory)
{
batchLockup = new SablierBatchLockup();
merkleLockupFactory = new SablierMerkleLockupFactory();
merkleFactory = new SablierMerkleFactory();
}
}
4 changes: 2 additions & 2 deletions shell/deploy-multi-chain.sh
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ for chain in "${provided_chains[@]}"; do
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}')
merkleFactory_address=$(echo "${output}" | awk '/merkleFactory: contract/{print $NF}')
nftDescriptor_address=$(echo "${output}" | awk '/nftDescriptor: contract/{print $NF}')

# Save to the chain file
Expand All @@ -372,7 +372,7 @@ for chain in "${provided_chains[@]}"; do
echo "SablierLockupTranched = ${lockupTranched_address}"
echo "Periphery Contracts"
echo "SablierBatchLockup = ${batchLockup_address}"
echo "SablierMerkleLockupFactory = ${merkleLockupFactory_address}"
echo "SablierMerkleFactory = ${merkleFactory_address}"
} >> "$chain_file"

echo -e "${SC}${TICK} Deployed on ${chain}. You can find the addresses in ${chain_file}${NC}"
Expand Down
6 changes: 4 additions & 2 deletions shell/prepare-artifacts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,16 @@ cp out-optimized/Errors.sol/Errors.json $core_libraries

periphery=./artifacts/periphery
cp out-optimized/SablierBatchLockup.sol/SablierBatchLockup.json $periphery
cp out-optimized/SablierMerkleFactory.sol/SablierMerkleFactory.json $periphery
cp out-optimized/SablierMerkleInstant.sol/SablierMerkleInstant.json $periphery
cp out-optimized/SablierMerkleLL.sol/SablierMerkleLL.json $periphery
cp out-optimized/SablierMerkleLockupFactory.sol/SablierMerkleLockupFactory.json $periphery
cp out-optimized/SablierMerkleLT.sol/SablierMerkleLT.json $periphery

periphery_interfaces=./artifacts/periphery/interfaces
cp out-optimized/ISablierBatchLockup.sol/ISablierBatchLockup.json $periphery_interfaces
cp out-optimized/ISablierMerkleFactory.sol/ISablierMerkleFactory.json $periphery_interfaces
cp out-optimized/ISablierMerkleInstant.sol/ISablierMerkleInstant.json $periphery_interfaces
cp out-optimized/ISablierMerkleLL.sol/ISablierMerkleLL.json $periphery_interfaces
cp out-optimized/ISablierMerkleLockupFactory.sol/ISablierMerkleLockupFactory.json $periphery_interfaces
cp out-optimized/ISablierMerkleLT.sol/ISablierMerkleLT.json $periphery_interfaces

periphery_libraries=./artifacts/periphery/libraries
Expand Down
4 changes: 2 additions & 2 deletions shell/update-precompiles.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ batch_lockup=$(cat out-optimized/SablierBatchLockup.sol/SablierBatchLockup.json
lockup_dynamic=$(cat out-optimized/SablierLockupDynamic.sol/SablierLockupDynamic.json | jq -r '.bytecode.object' | cut -c 3-)
lockup_linear=$(cat out-optimized/SablierLockupLinear.sol/SablierLockupLinear.json | jq -r '.bytecode.object' | cut -c 3-)
lockup_tranched=$(cat out-optimized/SablierLockupTranched.sol/SablierLockupTranched.json | jq -r '.bytecode.object' | cut -c 3-)
merkle_lockup_factory=$(cat out-optimized/SablierMerkleLockupFactory.sol/SablierMerkleLockupFactory.json | jq -r '.bytecode.object' | cut -c 3-)
merkle_factory=$(cat out-optimized/SablierMerkleFactory.sol/SablierMerkleFactory.json | jq -r '.bytecode.object' | cut -c 3-)
nft_descriptor=$(cat out-optimized/LockupNFTDescriptor.sol/LockupNFTDescriptor.json | jq -r '.bytecode.object' | cut -c 3-)

precompiles_path="precompiles/Precompiles.sol"
Expand All @@ -30,7 +30,7 @@ sd "(BYTECODE_BATCH_LOCKUP =)[^;]+;" "\$1 hex\"$batch_lockup\";" $precompiles_pa
sd "(BYTECODE_LOCKUP_DYNAMIC =)[^;]+;" "\$1 hex\"$lockup_dynamic\";" $precompiles_path
sd "(BYTECODE_LOCKUP_LINEAR =)[^;]+;" "\$1 hex\"$lockup_linear\";" $precompiles_path
sd "(BYTECODE_LOCKUP_TRANCHED =)[^;]+;" "\$1 hex\"$lockup_tranched\";" $precompiles_path
sd "(BYTECODE_MERKLE_LOCKUP_FACTORY =)[^;]+;" "\$1 hex\"$merkle_lockup_factory\";" $precompiles_path
sd "(BYTECODE_MERKLE_FACTORY =)[^;]+;" "\$1 hex\"$merkle_factory\";" $precompiles_path
sd "(BYTECODE_NFT_DESCRIPTOR =)[^;]+;" "\$1 hex\"$nft_descriptor\";" $precompiles_path

# Reformat the code with Forge
Expand Down
Loading