Skip to content
Merged
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
34 changes: 18 additions & 16 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,18 @@
Feel free to dive in! [Open](../../issues/new) an issue, [start](../../discussions/new) a discussion or submit a PR. For
any informal concerns or feedback, please join our [Discord server](https://discord.gg/bSwRCwWRsT).

Contributions to Sablier Airdrops are welcome by anyone interested in writing more tests, improving readability,
optimizing for gas efficiency, or extending the protocol via new features.
Contributions are welcome by anyone interested in writing more tests, improving readability, optimizing for gas
efficiency, or extending the protocol via new features.

## Pre Requisites

You will need the following software on your machine:

- [Git](https://git-scm.com/downloads)
- [Foundry](https://github.com/foundry-rs/foundry)
- [Node.Js](https://nodejs.org/en/download/)
- [Bun](https://bun.sh/)
- [Rust](https://rust-lang.org/tools/install)
- [Bulloak](https://bulloak.dev/)
- [Node.js](https://nodejs.org) (v20+)
- [Just](https://github.com/casey/just) (command runner)
- [Bun](https://bun.sh) (package manager)
- [Ni](https://github.com/antfu-collective/ni) (package manager resolver)
- [Foundry](https://github.com/foundry-rs/foundry) (EVM development framework)
- [Rust](https://rust-lang.org/tools/install) (Rust compiler)
- [Bulloak](https://bulloak.dev) (CLI for checking tests)

In addition, familiarity with [Solidity](https://soliditylang.org/) is requisite.

Expand All @@ -32,8 +31,8 @@ $ git clone git@github.com:sablier-labs/airdrops.git
Then, inside the project's directory, run this to install the Node.js dependencies and build the contracts:

```shell
$ bun install
$ bun run build
$ just install
$ just build
```

Switch to the `staging` branch, where all development work should be done:
Expand All @@ -44,19 +43,22 @@ $ git switch staging

Now you can start making changes.

To see a list of all available scripts:
To see a list of all available scripts, run this command:

```shell
$ bun run
$ just --list
```

## Pull Requests

When making a pull request, ensure that:

- The base branch is `staging`.
- The base development branch is `staging`.
- All tests pass.
- Fork testing requires environment variables to be set up in the forked repo.
- Concrete tests are generated using Bulloak and the Branching Tree Technique (BTT).
- You can learn more about this on the [Bulloak website](https://bulloak.dev).
- If you modify a test tree, use this command to generate the corresponding test contract that complies with BTT:
`bulloak scaffold -wf /path/to/file.tree`
- Code coverage remains the same or greater.
- All new code adheres to the style guide:
- All lint checks pass.
Expand Down
18 changes: 5 additions & 13 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,4 @@
import "./node_modules/@sablier/devkit/just/evm.just"

default:
@just --list

test *args:
forge test --nmc ChainlinkOracle_Fork_Test {{ args }}
@just --list
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
"@chainlink/contracts": "1.3.0",
"@openzeppelin/contracts": "5.3.0",
"@prb/math": "4.1.0",
"@sablier/lockup": "github:sablier-labs/lockup#0c8f8fa",
"@sablier/evm-utils": "github:sablier-labs/evm-utils#e81a04b"
"@sablier/lockup": "github:sablier-labs/lockup#07303b1",
"@sablier/evm-utils": "github:sablier-labs/evm-utils#e66fb2d"
},
"devDependencies": {
"@sablier/devkit": "github:sablier-labs/devkit",
Expand Down
46 changes: 0 additions & 46 deletions scripts/solidity/Base.sol

This file was deleted.

2 changes: 1 addition & 1 deletion scripts/solidity/CreateMerkleInstant.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
pragma solidity >=0.8.22 <0.9.0;

import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { BaseScript } from "@sablier/evm-utils/src/tests/BaseScript.sol";
import { ISablierMerkleInstant } from "../../src/interfaces/ISablierMerkleInstant.sol";
import { SablierFactoryMerkleInstant } from "../../src/SablierFactoryMerkleInstant.sol";
import { MerkleInstant } from "../../src/types/DataTypes.sol";
import { BaseScript } from "./Base.sol";

/// @dev Creates a dummy MerkleInstant campaign.
contract CreateMerkleInstant is BaseScript {
Expand Down
2 changes: 1 addition & 1 deletion scripts/solidity/CreateMerkleLL.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ pragma solidity >=0.8.22 <0.9.0;

import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { ud60x18 } from "@prb/math/src/UD60x18.sol";
import { BaseScript } from "@sablier/evm-utils/src/tests/BaseScript.sol";
import { ISablierLockup } from "@sablier/lockup/src/interfaces/ISablierLockup.sol";
import { ISablierMerkleLL } from "../../src/interfaces/ISablierMerkleLL.sol";
import { SablierFactoryMerkleLL } from "../../src/SablierFactoryMerkleLL.sol";
import { MerkleLL } from "../../src/types/DataTypes.sol";
import { BaseScript } from "./Base.sol";

/// @dev Creates a dummy campaign to airdrop tokens through Lockup Linear.
contract CreateMerkleLL is BaseScript {
Expand Down
3 changes: 1 addition & 2 deletions scripts/solidity/CreateMerkleLT.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ pragma solidity >=0.8.22 <0.9.0;

import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { ud2x18 } from "@prb/math/src/UD2x18.sol";
import { BaseScript } from "@sablier/evm-utils/src/tests/BaseScript.sol";
import { ISablierLockup } from "@sablier/lockup/src/interfaces/ISablierLockup.sol";

import { ISablierMerkleLT } from "../../src/interfaces/ISablierMerkleLT.sol";
import { SablierFactoryMerkleLT } from "../../src/SablierFactoryMerkleLT.sol";

import { MerkleLT } from "../../src/types/DataTypes.sol";
import { BaseScript } from "./Base.sol";

/// @dev Creates a dummy campaign to airdrop tokens through Lockup Tranched.
contract CreateMerkleLT is BaseScript {
Expand Down
2 changes: 1 addition & 1 deletion scripts/solidity/CreateMerkleVCA.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
pragma solidity >=0.8.22 <0.9.0;

import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { BaseScript } from "@sablier/evm-utils/src/tests/BaseScript.sol";
import { ISablierMerkleVCA } from "../../src/interfaces/ISablierMerkleVCA.sol";
import { SablierFactoryMerkleVCA } from "../../src/SablierFactoryMerkleVCA.sol";
import { MerkleVCA } from "../../src/types/DataTypes.sol";
import { BaseScript } from "./Base.sol";

/// @dev Creates a dummy MerkleVCA campaign.
contract CreateMerkleVCA is BaseScript {
Expand Down
2 changes: 1 addition & 1 deletion scripts/solidity/DeployDeterministicFactories.s.sol
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.8.22 <0.9.0;

import { BaseScript } from "@sablier/evm-utils/src/tests/BaseScript.sol";
import { SablierFactoryMerkleInstant } from "../../src/SablierFactoryMerkleInstant.sol";
import { SablierFactoryMerkleLL } from "../../src/SablierFactoryMerkleLL.sol";
import { SablierFactoryMerkleLT } from "../../src/SablierFactoryMerkleLT.sol";
import { SablierFactoryMerkleVCA } from "../../src/SablierFactoryMerkleVCA.sol";
import { BaseScript } from "./Base.sol";

/// @notice Deploys the FactoryMerkle contracts at deterministic addresses.
/// @dev Reverts if any contract has already been deployed.
Expand Down
2 changes: 1 addition & 1 deletion scripts/solidity/DeployFactories.s.sol
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.8.22 <0.9.0;

import { BaseScript } from "@sablier/evm-utils/src/tests/BaseScript.sol";
import { SablierFactoryMerkleInstant } from "../../src/SablierFactoryMerkleInstant.sol";
import { SablierFactoryMerkleLL } from "../../src/SablierFactoryMerkleLL.sol";
import { SablierFactoryMerkleLT } from "../../src/SablierFactoryMerkleLT.sol";
import { SablierFactoryMerkleVCA } from "../../src/SablierFactoryMerkleVCA.sol";
import { BaseScript } from "./Base.sol";

/// @notice Deploys the FactoryMerkle contracts.
contract DeployFactories is BaseScript {
Expand Down
39 changes: 29 additions & 10 deletions src/SablierMerkleInstant.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.s

import { SablierMerkleBase } from "./abstracts/SablierMerkleBase.sol";
import { ISablierMerkleInstant } from "./interfaces/ISablierMerkleInstant.sol";
import { Errors } from "./libraries/Errors.sol";
import { MerkleInstant } from "./types/DataTypes.sol";

/*
Expand Down Expand Up @@ -71,10 +70,10 @@ contract SablierMerkleInstant is
payable
override
{
// Check, Effect and Interaction: Pre-process the claim parameters.
// Check, Effect and Interaction: Pre-process the claim parameters on behalf of the recipient.
_preProcessClaim(index, recipient, amount, merkleProof);

// Interaction: Post-process the claim parameters.
// Interaction: Post-process the claim parameters on behalf of the recipient.
_postProcessClaim({ index: index, recipient: recipient, to: recipient, amount: amount });
}

Expand All @@ -88,19 +87,39 @@ contract SablierMerkleInstant is
external
payable
override
notZeroAddress(to)
{
// Check: `to` must not be the zero address.
if (to == address(0)) {
revert Errors.SablierMerkleInstant_ToZeroAddress();
}

// Check, Effect and Interaction: Pre-process the claim parameters.
// Check, Effect and Interaction: Pre-process the claim parameters on behalf of `msg.sender`.
_preProcessClaim({ index: index, recipient: msg.sender, amount: amount, merkleProof: merkleProof });

// Interaction: Post-process the claim parameters.
// Interaction: Post-process the claim parameters on behalf of `msg.sender`.
_postProcessClaim({ index: index, recipient: msg.sender, to: to, amount: amount });
}

/// @inheritdoc ISablierMerkleInstant
function claimViaSig(
uint256 index,
address recipient,
address to,
uint128 amount,
bytes32[] calldata merkleProof,
bytes calldata signature
)
external
payable
override
notZeroAddress(to)
{
// Check: the signature is valid and the recovered signer matches the recipient.
_checkSignature(index, recipient, to, amount, signature);

// Check, Effect and Interaction: Pre-process the claim parameters on behalf of the recipient.
_preProcessClaim(index, recipient, amount, merkleProof);

// Interaction: Post-process the claim parameters on behalf of the recipient.
_postProcessClaim(index, recipient, to, amount);
}

/*//////////////////////////////////////////////////////////////////////////
PRIVATE STATE-CHANGING FUNCTIONS
//////////////////////////////////////////////////////////////////////////*/
Expand Down
39 changes: 29 additions & 10 deletions src/SablierMerkleLL.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { Lockup, LockupLinear } from "@sablier/lockup/src/types/DataTypes.sol";

import { SablierMerkleLockup } from "./abstracts/SablierMerkleLockup.sol";
import { ISablierMerkleLL } from "./interfaces/ISablierMerkleLL.sol";
import { Errors } from "./libraries/Errors.sol";
import { MerkleLL } from "./types/DataTypes.sol";

/*
Expand Down Expand Up @@ -104,10 +103,10 @@ contract SablierMerkleLL is
payable
override
{
// Check, Effect and Interaction: Pre-process the claim parameters.
// Check, Effect and Interaction: Pre-process the claim parameters on behalf of the recipient.
_preProcessClaim(index, recipient, amount, merkleProof);

// Effect and Interaction: Post-process the claim parameters.
// Effect and Interaction: Post-process the claim parameters on behalf of the recipient.
_postProcessClaim({ index: index, recipient: recipient, to: recipient, amount: amount });
}

Expand All @@ -121,19 +120,39 @@ contract SablierMerkleLL is
external
payable
override
notZeroAddress(to)
{
// Check: `to` must not be the zero address.
if (to == address(0)) {
revert Errors.SablierMerkleLL_ToZeroAddress();
}

// Check, Effect and Interaction: Pre-process the claim parameters.
// Check, Effect and Interaction: Pre-process the claim parameters on behalf of `msg.sender`.
_preProcessClaim({ index: index, recipient: msg.sender, amount: amount, merkleProof: merkleProof });

// Effect and Interaction: Post-process the claim parameters.
// Effect and Interaction: Post-process the claim parameters on behalf of `msg.sender`.
_postProcessClaim({ index: index, recipient: msg.sender, to: to, amount: amount });
}

/// @inheritdoc ISablierMerkleLL
function claimViaSig(
uint256 index,
address recipient,
address to,
uint128 amount,
bytes32[] calldata merkleProof,
bytes calldata signature
)
external
payable
override
notZeroAddress(to)
{
// Check: the signature is valid and the recovered signer matches the recipient.
_checkSignature(index, recipient, to, amount, signature);

// Check, Effect and Interaction: Pre-process the claim parameters on behalf of the recipient.
_preProcessClaim(index, recipient, amount, merkleProof);

// Effect and Interaction: Post-process the claim parameters on behalf of the recipient.
_postProcessClaim(index, recipient, to, amount);
}

/*//////////////////////////////////////////////////////////////////////////
PRIVATE STATE-CHANGING FUNCTIONS
//////////////////////////////////////////////////////////////////////////*/
Expand Down
Loading
Loading