Skip to content

Commit

Permalink
feat: adds ISablierLockup and ISablierLockupBase
Browse files Browse the repository at this point in the history
refactor: modifies Datatypes
refactor: deletes individual lockup contracts and interfaces

feat: adds SablierLockupBase and SablierLockup
feat: spin out VestingMath library out of Helpers library
refactor: update errors

refactor: make periphery and merkle lockup contracts compatible with singelton lockup

chore: update count of inherited components

chore: update deployment scripts

build: update shell scripts

chore: update precompiles contract

style: fix lint warnings

feat: include libraries in artifacts

fix: bug

refactor: move endTime check into helpers

refactor: address feedback (#1079)

* refactor: address feedback

* refactor: move calculate segments/tranches in Helpers

refactor: revert constant in library change
refactor: re introduce _checkCliffAndEndTime function

* refactor: polish code

* chore: remove unneeded import

* add stream id in _create

* use ISablierLockupBase.isTransferable

---------

Co-authored-by: smol-ninja <[email protected]>

refactor: prefix errors name used in Helpers with SablierHelpers
  • Loading branch information
smol-ninja committed Nov 11, 2024
1 parent 138877e commit 8ca1274
Show file tree
Hide file tree
Showing 49 changed files with 1,998 additions and 2,785 deletions.
3 changes: 1 addition & 2 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ Vulnerabilities contingent upon the occurrence of any of the following also are
Sablier Lockup has been developed with a number of technical assumptions in mind. For a disclosure to qualify as a
vulnerability, it must adhere to these assumptions as well:

- The immutable variables `MAX_SEGMENT_COUNT` and `MAX_TRANCHE_COUNT` have values that cannot lead to an overflow of the
block gas limit.
- The immutable `MAX_COUNT` has value that cannot lead to an overflow of the block gas limit.
- The total supply of any ERC-20 token remains below 2<sup>128</sup> - 1, i.e., `type(uint128).max`.
- The `transfer` and `transferFrom` methods of any ERC-20 token strictly reduce the sender's balance by the transfer
amount and increase the recipient's balance by the same amount. In other words, tokens that charge fees on transfers
Expand Down
8 changes: 3 additions & 5 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,7 @@

[profile.smt.model_checker.contracts]
"src/core/LockupNFTDescriptor.sol" = ["LockupNFTDescriptor"]
"src/core/SablierLockupDynamic.sol" = ["SablierLockupDynamic"]
"src/core/SablierLockupLinear.sol" = ["SablierLockupLinear"]
"src/core/SablierLockupTranched.sol" = ["SablierLockupTranched"]
"src/core/SablierLockup.sol" = ["SablierLockup"]

# Test the optimized contracts without re-compiling them
[profile.test-optimized]
Expand Down Expand Up @@ -100,7 +98,7 @@
scroll = { key = "${SCROLLSCAN_API_KEY}" }
sepolia = { key = "${SEPOLIASCAN_KEY}" }
taiko_mainnet = { key = "${TAIKO_MAINNET_API_KEY}" }

[fmt]
bracket_spacing = true
int_types = "long"
Expand Down Expand Up @@ -134,4 +132,4 @@
sei_testnet = "https://evm-rpc.arctic-1.seinetwork.io"
sepolia = "${SEPOLIA_RPC_URL}"
taiko_hekla = "https://rpc.hekla.taiko.xyz"
taiko_mainnet = "https://rpc.mainnet.taiko.xyz"
taiko_mainnet = "https://rpc.mainnet.taiko.xyz"
165 changes: 30 additions & 135 deletions precompiles/Precompiles.sol

Large diffs are not rendered by default.

57 changes: 20 additions & 37 deletions script/Base.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ contract BaseScript is Script {
using Strings for uint256;
using stdJson for string;

/// @dev The default value for `segmentCountMap` and `trancheCountMap`.
/// @dev The default value for `maxCountMap`.
uint256 internal constant DEFAULT_MAX_COUNT = 500;

/// @dev Included to enable compilation of the script without a $MNEMONIC environment variable.
Expand All @@ -27,11 +27,8 @@ contract BaseScript is Script {
/// @dev Used to derive the broadcaster's address if $EOA is not defined.
string internal mnemonic;

/// @dev Maximum segment count mapped by the chain Id.
mapping(uint256 chainId => uint256 count) internal segmentCountMap;

/// @dev Maximum tranche count mapped by the chain Id.
mapping(uint256 chainId => uint256 count) internal trancheCountMap;
/// @dev Maximum count for segments and tranches mapped by the chain Id.
mapping(uint256 chainId => uint256 count) internal maxCountMap;

/// @dev Initializes the transaction broadcaster like this:
///
Expand All @@ -49,15 +46,12 @@ contract BaseScript is Script {
(broadcaster,) = deriveRememberKey({ mnemonic: mnemonic, index: 0 });
}

// Populate the segment and tranche count map.
populateSegmentAndTrancheCountMap();
// Populate the max count map for segments and tranches.
populateMaxCountMap();

// If there is no maximum value set for a specific chain, use the default value.
if (segmentCountMap[block.chainid] == 0) {
segmentCountMap[block.chainid] = DEFAULT_MAX_COUNT;
}
if (trancheCountMap[block.chainid] == 0) {
trancheCountMap[block.chainid] = DEFAULT_MAX_COUNT;
if (maxCountMap[block.chainid] == 0) {
maxCountMap[block.chainid] = DEFAULT_MAX_COUNT;
}
}

Expand Down Expand Up @@ -86,53 +80,42 @@ contract BaseScript is Script {
return json.readString(".version");
}

/// @dev Populates the segment & tranche count map. Values can be updated using the `update-counts.sh` script.
function populateSegmentAndTrancheCountMap() internal {
/// @dev Updates max values for segments and tranches. Values can be updated using the `update-counts.sh` script.
function populateMaxCountMap() internal {
// forgefmt: disable-start

// Arbitrum chain ID
segmentCountMap[42161] = 1160;
trancheCountMap[42161] = 1200;
maxCountMap[42161] = 1160;

// Avalanche chain ID.
segmentCountMap[43114] = 520;
trancheCountMap[43114] = 540;
maxCountMap[43114] = 520;

// Base chain ID.
segmentCountMap[8453] = 2170;
trancheCountMap[8453] = 2270;
maxCountMap[8453] = 2170;

// Blast chain ID.
segmentCountMap[81457] = 1080;
trancheCountMap[81457] = 1120;
maxCountMap[81457] = 1080;

// BNB chain ID.
segmentCountMap[56] = 4820;
trancheCountMap[56] = 5130;
maxCountMap[56] = 4820;

// Ethereum chain ID.
segmentCountMap[1] = 1080;
trancheCountMap[1] = 1120;
maxCountMap[1] = 1080;

// Gnosis chain ID.
segmentCountMap[100] = 600;
trancheCountMap[100] = 620;
maxCountMap[100] = 600;

// Optimism chain ID.
segmentCountMap[10] = 1080;
trancheCountMap[10] = 1120;
maxCountMap[10] = 1080;

// Polygon chain ID.
segmentCountMap[137] = 1080;
trancheCountMap[137] = 1120;
maxCountMap[137] = 1080;

// Scroll chain ID.
segmentCountMap[534352] = 330;
trancheCountMap[534352] = 340;
maxCountMap[534352] = 330;

// Sepolia chain ID.
segmentCountMap[11155111] = 1080;
trancheCountMap[11155111] = 1120;
maxCountMap[11155111] = 1080;

// forgefmt: disable-end
}
Expand Down
15 changes: 3 additions & 12 deletions script/core/DeployCore.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
pragma solidity >=0.8.22 <0.9.0;

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 { SablierLockup } from "../../src/core/SablierLockup.sol";

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

Expand All @@ -14,16 +12,9 @@ contract DeployCore is BaseScript {
public
virtual
broadcast
returns (
LockupNFTDescriptor nftDescriptor,
SablierLockupDynamic lockupDynamic,
SablierLockupLinear lockupLinear,
SablierLockupTranched lockupTranched
)
returns (LockupNFTDescriptor nftDescriptor, SablierLockup lockup)
{
nftDescriptor = new LockupNFTDescriptor();
lockupDynamic = new SablierLockupDynamic(initialAdmin, nftDescriptor, segmentCountMap[block.chainid]);
lockupLinear = new SablierLockupLinear(initialAdmin, nftDescriptor);
lockupTranched = new SablierLockupTranched(initialAdmin, nftDescriptor, trancheCountMap[block.chainid]);
lockup = new SablierLockup(initialAdmin, nftDescriptor, maxCountMap[block.chainid]);
}
}
29 changes: 0 additions & 29 deletions script/core/DeployCore2.s.sol

This file was deleted.

18 changes: 3 additions & 15 deletions script/core/DeployDeterministicCore.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@
pragma solidity >=0.8.22 <0.9.0;

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 { SablierLockup } from "../../src/core/SablierLockup.sol";
import { BaseScript } from "../Base.s.sol";

/// @notice Deploys all Core contracts at deterministic addresses across chains.
Expand All @@ -15,19 +12,10 @@ contract DeployDeterministicCore is BaseScript {
public
virtual
broadcast
returns (
LockupNFTDescriptor nftDescriptor,
SablierLockupDynamic lockupDynamic,
SablierLockupLinear lockupLinear,
SablierLockupTranched lockupTranched
)
returns (LockupNFTDescriptor nftDescriptor, SablierLockup lockup)
{
bytes32 salt = constructCreate2Salt();
nftDescriptor = new LockupNFTDescriptor{ salt: salt }();
lockupDynamic =
new SablierLockupDynamic{ salt: salt }(initialAdmin, nftDescriptor, segmentCountMap[block.chainid]);
lockupLinear = new SablierLockupLinear{ salt: salt }(initialAdmin, nftDescriptor);
lockupTranched =
new SablierLockupTranched{ salt: salt }(initialAdmin, nftDescriptor, trancheCountMap[block.chainid]);
lockup = new SablierLockup{ salt: salt }(initialAdmin, nftDescriptor, maxCountMap[block.chainid]);
}
}
33 changes: 0 additions & 33 deletions script/core/DeployDeterministicCore2.s.sol

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,22 @@
pragma solidity >=0.8.22 <0.9.0;

import { ILockupNFTDescriptor } from "../../src/core/interfaces/ILockupNFTDescriptor.sol";
import { SablierLockupLinear } from "../../src/core/SablierLockupLinear.sol";

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

/// @dev Deploys {SablierLockupLinear} at a deterministic address across chains.
/// @notice Deploys {SablierLockup} at a deterministic address across chains.
/// @dev Reverts if the contract has already been deployed.
contract DeployDeterministicLockupLinear is BaseScript {
contract DeployDeterministicLockup is BaseScript {
function run(
address initialAdmin,
ILockupNFTDescriptor initialNFTDescriptor
ILockupNFTDescriptor nftDescriptor
)
public
virtual
broadcast
returns (SablierLockupLinear lockupLinear)
returns (SablierLockup lockup)
{
bytes32 salt = constructCreate2Salt();
lockupLinear = new SablierLockupLinear{ salt: salt }(initialAdmin, initialNFTDescriptor);
lockup = new SablierLockup{ salt: salt }(initialAdmin, nftDescriptor, maxCountMap[block.chainid]);
}
}
25 changes: 0 additions & 25 deletions script/core/DeployDeterministicLockupDynamic.s.sol

This file was deleted.

25 changes: 0 additions & 25 deletions script/core/DeployDeterministicLockupTranched.s.sol

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,21 @@
pragma solidity >=0.8.22 <0.9.0;

import { ILockupNFTDescriptor } from "../../src/core/interfaces/ILockupNFTDescriptor.sol";
import { SablierLockupLinear } from "../../src/core/SablierLockupLinear.sol";
import { SablierLockup } from "../../src/core/SablierLockup.sol";

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

contract DeployLockupLinear is BaseScript {
/// @notice Deploys {SablierLockup} contract.
contract DeployLockup is BaseScript {
function run(
address initialAdmin,
ILockupNFTDescriptor initialNFTDescriptor
ILockupNFTDescriptor nftDescriptor
)
public
virtual
broadcast
returns (SablierLockupLinear lockupLinear)
returns (SablierLockup lockup)
{
lockupLinear = new SablierLockupLinear(initialAdmin, initialNFTDescriptor);
lockup = new SablierLockup(initialAdmin, nftDescriptor, maxCountMap[block.chainid]);
}
}
Loading

0 comments on commit 8ca1274

Please sign in to comment.