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: implement airstreams with lockup dynamic #282

Closed
wants to merge 2 commits into from

Conversation

smol-ninja
Copy link
Member

@smol-ninja smol-ninja commented Feb 6, 2024

Closes #274.

Summary

  1. To create LD campaign.
function createMerkleLockupLD(baseParams, lockupDynamic, ipfsCID, aggregateAmount, recipientsCount)
    external returns (merkleLockupLD);
  1. To claim Airdrop from an LD campaign.
function claim(index, recipient, amount, segments, merkleProof)
    external returns (streamId);
  1. Adds a new event.
event CreateMerkleLockupLD(merkleLockupLD, baseParams, lockupDynamic, ipfsCID, aggregateAmount, recipientsCount);
  • Integrations tests for MerkleLockupLD
  • Fork tests for MerkleLockupLD

Security consideration

If protocol fee is not zero, claiming will fail. When protocol fee is non-zero, amount in claim() must include the protocol fee.

@andreivladbrg
Copy link
Member

Let's add an amount parameter in the claim function regardless we remove the protocol fee or not. It would save us gas if we do so

@smol-ninja
Copy link
Member Author

Yeah. I agree with that.

@smol-ninja smol-ninja force-pushed the feat/MerkleStreamerLD branch from 2eb5a19 to 4f34a57 Compare February 7, 2024 19:55
Copy link
Member

@andreivladbrg andreivladbrg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work, Shub!

I'll leave these comments for now (might find more things later), so we can keep things moving

test/fork/merkle-lockup/MerkleLockupLL.t.sol Outdated Show resolved Hide resolved
src/SablierV2MerkleLockupLD.sol Outdated Show resolved Hide resolved
src/interfaces/ISablierV2MerkleLockupFactory.sol Outdated Show resolved Hide resolved
{
// Generate the Merkle tree leaf by hashing the corresponding parameters. Hashing twice prevents second
// preimage attacks.
bytes32 leaf = keccak256(bytes.concat(keccak256(abi.encode(index, recipient, segments))));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's include amount in the leaf

so that the leaf is the same as LL + segments. it would make things easier for merkle-api (i think)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense. I have changed it to

bytes32 leaf = keccak256(bytes.concat(keccak256(abi.encode(index, recipient, amount, segments))));

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andreivladbrg reopening this conversation because I disagree that we should include amount in the leaf.

When the protocol fee is non-zero, constructing Merkle tree would require the UI to reverse calculate all the claim amounts to include the protocol fee.

Consider the below simple example

  1. Segments sum to 10,000 for each user.
  2. If protocol fee = 1%, UI would have to reverse calculate the amount as 10,000/0.9 = 11111 and include it in the Merkle tree.
  3. When a user claims, 11111*0.9 must match the segments sum otherwise claim would fail. Now because step 2 requires division in the UI, it is exposed to floating point errors leading to users not being able to claim (since we have strict equality depositAmount != segmentAmountsSum). This may require re-submitting the Merkle tree.

So it is safe to not include amount in the Merkle leaf and let it be an input parameter into the claim function.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are correct

i will create a separate discussion regarding what to include in the Merkle tree because Mircea told me that there are some considerations we have to take into account

src/interfaces/ISablierV2MerkleLockupLD.sol Outdated Show resolved Hide resolved
test/fork/merkle-lockup/MerkleLockupLD.t.sol Outdated Show resolved Hide resolved
test/fork/merkle-lockup/MerkleLockupLL.t.sol Outdated Show resolved Hide resolved
test/utils/Defaults.sol Outdated Show resolved Hide resolved
test/utils/Defaults.sol Outdated Show resolved Hide resolved
test/fork/merkle-lockup/MerkleLockupLD.t.sol Outdated Show resolved Hide resolved
@smol-ninja
Copy link
Member Author

Great feedbacks @andreivladbrg and thank you for the review.

@smol-ninja smol-ninja force-pushed the feat/MerkleStreamerLD branch 3 times, most recently from 632d533 to b5e7199 Compare February 12, 2024 23:10
@andreivladbrg
Copy link
Member

Until we make a decision regarding this discussion, I suggest we put this PR on hold.

test: integration and fork tests for MerkleLockupLD

refactor: add NatSpec format to events

feat: include amount in claim function

feat: include "amount" in LD leaf
test: refine fork tests
refactor: use "airstream campaign" terminology

test: replace streamDurations with endTime in Vars struct
@smol-ninja
Copy link
Member Author

I will fix the merge conflicts after we have made this decision.

@smol-ninja
Copy link
Member Author

Closing it as discussed in #288.

@smol-ninja smol-ninja closed this Mar 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants