0xSplits is a trustless protocol for splitting on-chain income. The protocol takes the form of a “hyperstructure”—a permissionless piece of infrastructure that distributes value to all users, operates at gas cost, and persists as long as the underlying blockchain reaches consensus. The smart contracts have been deployed to Ethereum mainnet and independently audited by Shipyard.
The core components of the income-splitting mechanism are Splits and Recipients. A Split is a payable smart contract that receives ETH and ERC-20 tokens and proportionally allocates received funds to Recipients. A Recipient can be any address associated with an EOA (externally owned account) or smart contract. As of 3/27/2022, 580 ETH and 16 different ERC20 tokens have flowed through 267 Splits.
Splits can be designated as either Mutable or Immutable at creation, with Mutable Splits requiring a Controller address (the Controller of Immutable Splits is set to 0x0
, the Null Address). The Controller can modify a Mutable Split’s Recipients, percent allocations, and Distributor Fee after a Split has been created. The Controller can also transfer control to another address. While a Mutable Split can be set to immutable, an Immutable Split cannot be set to mutable. As of writing, 170 Immutable Splits and 97 Mutable Splits have been deployed, splitting income to 644 unique Recipients.
Splits are able to run at gas cost by relying on a third-party distributor to execute the transaction that updates Recipients’ withdrawable balances. In exchange for incurring gas costs, the distributor is rewarded with a Distributor Fee, a percentage of the total Split balance at the time of distribution. This fee can range anywhere from 0-10%. As of 3/27/22, the highest Distributor Fee earned is 0.22 ETH for a 0.1% Split. As the protocol’s documentation notes, a higher fee would likely lead to more frequent distributions, but the Recipients will be left splitting a smaller balance of funds.
We created a Dune dashboard with data analysis of existing Splits. Explore the data here.
createSplit
takes in four parameters:
Under the hood, createSplit
deploys a minimal proxy clone that redirects function calls to SplitWallet
; effectively, this Split proxy mimics the logic found in SplitWallet
but costs minimal gas to deploy. As a result, every Split has a unique address that can receive funds and send them to SplitMain
.
EIP-1167 defines a standard for a minimal proxy contract, but 0xSplits extends EIP-1167. Split proxies refrain from calling DELEGATECALL
in their receive
function to avoid delegating a function call to SplitWallet
. Instead, the receive
function emits a ReceiveEth
event, with parameters of the Split proxy address and the amount of ETH received. This modification allows proxies to accept ETH sent by send
and transfer
. Both of these functions only forward 2300 gas, which would not be enough to cover a DELEGATECALL
to SplitWallet
. Accepting ETH sent with send
and transfer
improves the composability of Splits since some accounts or smart contracts may send funds using these hard-capped functions. While this non-standard proxy pattern offers more flexibility for sending funds to Splits, this modification prevents Etherscan from verifying Split proxy contracts.
The technical architecture separating SplitMain
and SplitWallet
proxies allows balances to be stored at the account level. Since account balances are stored on SplitMain
and updated once a Split balance is distributed, Recipients can withdraw funds received from multiple Splits in one transaction.
Third parties can call distributeETH
and distributeERC20
to distribute Split balances to Recipients in exchange for a percentage of the total balance, defined as the Distributor Fee. Each ERC20 token requires a separate transaction call to distributeERC20
.
The protocol ensures that distributors cannot alter Recipient addresses or their percentage shares by storing a hash of the Recipients, percent allocations, and Distributor Fee when a Split is first created. When either distributeETH
or distributeERC20
is called, a similar hash is created with the function’s parameters. This hash must match the original hash stored for a particular Split.
ETH and ERC20 token balances can be withdrawn in one transaction. Balances are stored at the account level in SplitMain, so Recipients can withdraw funds from multiple Splits once they have been distributed. withdraw
takes in the Recipient address whose balances are being withdrawn as a parameter, meaning that anyone can withdraw funds on behalf of another account. Although the user interface currently only allows accounts to withdraw their own balances, users can manually withdraw for another account on Etherscan today. The 0xSplits team is in the process of adding delegated withdrawals to the user interface.
0xSplits is a powerful and intuitive form of public infrastructure. The protocol encourages communities to create novel income streams and distribute them efficiently without worrying about additional overhead costs. At the same time, third parties can profit from arbitrage by distributing Splits with fees that outweigh transaction costs.
The full composability of Splits also engenders positive feedback as Splits can flush funds to other Splits and smart contracts. As of writing, donations.0xsplits.eth
, the donations Split created by the team, is receiving income from 96 upstream Splits. Users should be cautious of sending funds to Mutable Splits that can be altered at any time, though the user interface provides sufficient warning on Mutable Split pages.
Thanks to everyone that helped get this review completed. Julian for the illustration, the 0xSplits team, and Andrew for the dashboard.