SablierMerkleLT
Inherits: ISablierMerkleLT, SablierMerkleLockup, SablierMerkleSignature
Title: SablierMerkleLT
See the documentation in ISablierMerkleLT.
State Variables
VESTING_START_TIME
Retrieves the start time of the vesting stream, as a Unix timestamp. Zero is a sentinel value for block.timestamp.
uint40 public immutable override VESTING_START_TIME
_tranchesWithPercentages
The tranches with their respective unlock percentages and durations.
MerkleLT.TrancheWithPercentage[] private _tranchesWithPercentages
Functions
constructor
Constructs the contract by initializing the immutable state variables, and max approving the Lockup contract.
constructor(
MerkleLT.ConstructorParams memory campaignParams,
address campaignCreator,
address comptroller
)
SablierMerkleBase(MerkleBase.ConstructorParams({
campaignCreator: campaignCreator,
campaignName: campaignParams.campaignName,
campaignStartTime: campaignParams.campaignStartTime,
claimType: campaignParams.claimType,
comptroller: comptroller,
expiration: campaignParams.expiration,
initialAdmin: campaignParams.initialAdmin,
ipfsCID: campaignParams.ipfsCID,
merkleRoot: campaignParams.merkleRoot,
token: campaignParams.token
}))
SablierMerkleLockup(MerkleLockup.ConstructorParams({
cancelable: campaignParams.cancelable,
lockup: campaignParams.lockup,
shape: campaignParams.shape,
transferable: campaignParams.transferable
}));
tranchesWithPercentages
Retrieves the tranches with their respective unlock percentages and durations.
function tranchesWithPercentages() external view override returns (MerkleLT.TrancheWithPercentage[] memory);
claim
Claim airdrop on behalf of eligible recipient. If the vesting end time is in the future, it creates a Lockup Tranched stream, otherwise it transfers the tokens directly to the recipient address.
It emits either {ClaimLTWithTransfer} or {ClaimLTWithVesting} event. Requirements:
CLAIM_TYPEmust beDEFAULT.- The current time must be greater than or equal to the campaign start time.
- The campaign must not have expired.
msg.valuemust not be less than the value returned by {COMPTROLLER.calculateMinFeeWei}.- The
indexmust not be claimed already. - The Merkle proof must be valid.
- All requirements from {ISablierLockupTranched.createWithTimestampsLT} must be met.
function claim(
uint256 index,
address recipient,
uint128 amount,
bytes32[] calldata merkleProof
)
external
payable
override
revertIfNot(ClaimType.DEFAULT);
Parameters
| Name | Type | Description |
|---|---|---|
index | uint256 | The index of the recipient in the Merkle tree. |
recipient | address | The address of the airdrop recipient. |
amount | uint128 | The amount of ERC-20 tokens allocated to the recipient. |
merkleProof | bytes32[] | The proof of inclusion in the Merkle tree. |
claimTo
Claim airdrop. If the vesting end time is in the future, it creates a Lockup Tranched stream with to address as the
stream recipient, otherwise it transfers the tokens directly to the to address.
It emits either {ClaimLTWithTransfer} or {ClaimLTWithVesting} event. Requirements:
CLAIM_TYPEmust beDEFAULT.msg.sendermust be the airdrop recipient.- The
tomust not be the zero address. - Refer to the requirements in {claim}.
function claimTo(
uint256 index,
address to,
uint128 amount,
bytes32[] calldata merkleProof
)
external
payable
override
revertIfNot(ClaimType.DEFAULT)
notZeroAddress(to);
Parameters
| Name | Type | Description |
|---|---|---|
index | uint256 | The index of the msg.sender in the Merkle tree. |
to | address | The address to which Lockup stream or ERC-20 tokens will be sent on behalf of msg.sender. |
amount | uint128 | The amount of ERC-20 tokens allocated to the msg.sender. |
merkleProof | bytes32[] | The proof of inclusion in the Merkle tree. |
claimViaAttestation
Claim airdrop using an external attestation from a trusted attestor (e.g., KYC verifier). If the vesting end time is in
the future, it creates a Lockup Tranched stream with to address as the stream recipient, otherwise it transfers the
tokens directly to the to address.
It emits either {ClaimLTWithTransfer} or {ClaimLTWithVesting} event. Notes:
- The attestation must be an EIP-712 signature from the attestor.
- See the example in the {claimViaSig} function.
- If the attestor is not set in the campaign, the attestor from the comptroller is used. Requirements:
msg.sendermust be the airdrop recipient.CLAIM_TYPEmust beATTEST.- The
tomust not be the zero address. - The attestor must not be the zero address.
- The
expireAttimestamp must not be in the past. - The attestation signature must be valid.
- Refer to the requirements in {claim}.
function claimViaAttestation(
uint256 index,
address to,
uint128 amount,
uint40 expireAt,
bytes32[] calldata merkleProof,
bytes calldata attestation
)
external
payable
override
revertIfNot(ClaimType.ATTEST)
notZeroAddress(to);
Parameters
| Name | Type | Description |
|---|---|---|
index | uint256 | The index of the msg.sender in the Merkle tree. |
to | address | The address to which Lockup stream or ERC-20 tokens will be sent on behalf of msg.sender. |
amount | uint128 | The amount of ERC-20 tokens allocated to the msg.sender. |
expireAt | uint40 | The timestamp after which the attestation signature is no longer valid. |
merkleProof | bytes32[] | The proof of inclusion in the Merkle tree. |
attestation | bytes | The EIP-712 signature from the attestor. |
claimViaSig
Claim airdrop on behalf of eligible recipient using an EIP-712 or EIP-1271 signature. If the vesting end time is in the
future, it creates a Lockup Tranched stream with to address as the stream recipient, otherwise it transfers the tokens
directly to the to address.
It emits either {ClaimLTWithTransfer} or {ClaimLTWithVesting} event. Requirements:
CLAIM_TYPEmust beDEFAULT.- If
recipientis an EOA, it must match the recovered signer. - If
recipientis a contract, it must implement the IERC-1271 interface. - The
tomust not be the zero address. - The
validFrommust be less than or equal to the current block timestamp. - Refer to the requirements in {claim}. Below is the example of typed data to be signed by the airdrop recipient, referenced from https://docs.metamask.io/wallet/how-to/sign-data/#example.
types: {
EIP712Domain: [
{ name: "name", type: "string" },
{ name: "chainId", type: "uint256" },
{ name: "verifyingContract", type: "address" },
],
Claim: [
{ name: "index", type: "uint256" },
{ name: "recipient", type: "address" },
{ name: "to", type: "address" },
{ name: "amount", type: "uint128" },
{ name: "validFrom", type: "uint40" },
],
},
domain: {
name: "Sablier Airdrops Protocol",
chainId: 1, // Chain on which the contract is deployed
verifyingContract: "0xTheAddressOfThisContract", // The address of this contract
},
primaryType: "Claim",
message: {
index: 2, // The index of the signer in the Merkle tree
recipient: "0xTheAddressOfTheRecipient", // The address of the airdrop recipient
to: "0xTheAddressReceivingTheTokens", // The address where recipient wants to transfer the tokens
amount: "1000000000000000000000", // The amount of tokens allocated to the recipient
validFrom: 1752425637 // The timestamp from which the claim signature is valid
},
function claimViaSig(
uint256 index,
address recipient,
address to,
uint128 amount,
uint40 validFrom,
bytes32[] calldata merkleProof,
bytes calldata signature
)
external
payable
override
revertIfNot(ClaimType.DEFAULT)
notZeroAddress(to);
Parameters
| Name | Type | Description |
|---|---|---|
index | uint256 | The index of the recipient in the Merkle tree. |
recipient | address | The address of the airdrop recipient who is providing the signature. |
to | address | The address to which Lockup stream or ERC-20 tokens will be sent on behalf of the recipient. |
amount | uint128 | The amount of ERC-20 tokens allocated to the recipient. |
validFrom | uint40 | The timestamp from which the claim signature is valid. |
merkleProof | bytes32[] | The proof of inclusion in the Merkle tree. |
signature | bytes | The EIP-712 or EIP-1271 signature from the airdrop recipient. |
_calculateStartTimeAndTranches
Calculates the vesting start time, and the tranches based on the claim amount and the unlock percentages for each tranche.
function _calculateStartTimeAndTranches(uint128 claimAmount)
private
view
returns (uint40 vestingStartTime, LockupTranched.Tranche[] memory tranches);
_postProcessClaim
Post-processes the claim execution by creating the stream or transferring the tokens directly and emitting an event.
function _postProcessClaim(uint256 index, address recipient, address to, uint128 amount, bool viaSig) private;