SplitV2
SplitV2 keeps the original vision of SplitV1 while decoupling the
underlying splitter implementation from where the distributed funds are held (previously SplitMain
, now Warehouse). This decoupling allows us to build different types of splitters with different trade-offs for different use cases.
At launch, we are offering "Push" and "Pull" splitters.
- Create at split.new (opens in a new tab)
- Github (opens in a new tab)
- Contracts & Natspec (opens in a new tab)
- SDK
- Audit (opens in a new tab)
How it works
- Each Split is a payable smart contract wallet. Each recipient has an address
and an ownership percent. ETH and ERC20s sent directly to the Split are held
in the Split's balance until
distribute
is called. - Recipients, ownerships, and keeper fees are stored onchain as calldata and re-passed as args and validated via hashing when needed.
- Each Split gets its own address and proxy for maximum composability with other
contracts onchain. For these proxies, we extended
EIP-1167 Minimal Proxy Contract (opens in a new tab) to
avoid
DELEGATECALL
insidereceive()
, allowing for Splits to accept hard gas-cappedsends
&transfers
. PullSplit
(opens in a new tab) acts very similar to the original Split the key difference being where funds pile up after distribution. All funds are held in the Warehouse after distribution.PushSplit
(opens in a new tab) sends funds directly to the recipients on distribution. These sends are hard gas-capped to limit the costs adversarial recipients may impose; failed sends are deposited into the Warehouse.- Each Split can now also act as a smart contract wallet with the owner
having full execution access from the Split's address. This allows the owner to pause
distributions, make arbitrary transactions and also sign data using
ERC1271
(opens in a new tab). - We recommend reviewing the contracts flow of funds.
Notes
-
When using the deterministic creation flow it is recommended to use a random salt to avoid collisions. Since these txns may technically be frontrun from the mempool, integrators should add necessary measures to handle such cases. Since the creation is deterministic, the deployed Split configuration is unaffected. Integrators can avoid this issue entirely by using
factory.createSplit
which handles salt generation onchain and cannot be frontrun. -
The contracts do not impose a maximum limit on the number of recipients for a Split. Consequently, the practical limit is governed by the gas limit of the network's blocks. Be cautious of this constraint when creating large Splits, as it may result in funds being irretrievably locked due to the gas limit restrictions of the network.
Breakdown of gas usage when distributing a split with 500 recipients. -
In terms of recipient allocations, the Split creator now sets the total number of shares. As such, recipients holding small shares may be negatively impacted by rounding on small distributions, potentially leading to financial losses. For further information on this topic, please refer to
this discussion on rounding issues
(opens in a new tab) andthis note on allocation size limitations
(opens in a new tab). -
We do not recommend setting a Warehouse withdrawal incentive for pull Splits. Such an incentive exposes the Split to draining from a malicious actor looping withdraws & deposits. An incentive on distribution is sufficient to encourage bots to pull funds out of the Warehouse, when sufficient. or comprehensive insights, please consult this
analysis
(opens in a new tab).