Announcing: PaymentSplitter.io
Save gas and securely divide earnings between project contributors.
While working on a recent project with a client here at NorthwestNFTs, we ran into a problem. Our client wanted the royalties on aftermarket sales to be split between many different accounts. They had advertised that they would be donating to charity, creating a community fund, and, of course, paying themselves and the artists. That’s a lot of addresses to manage, and OpenSea only lets you select one address to send royalties to for a set of art. Of course, the project lead could just have royalties sent to their account, and then divvy them up accordingly on a month to month basis, but now those royalties have transformed into an endless accounting task for some unlucky soul. We can do better than that.
Typically, to divide funds earned by a smart contract, we can import the PaymentSplitter template contract by OpenZeppelin. In the NFT use case, the contract is imported by the NFT contract and its functionality is used to divy up money earned from the primary sale. This solves the problem of splitting earnings for the mint sale, but royalties are paid out by OpenSea, not the minting contract, and OpenSea only accepts one address. To fix this, we can create a PaymentSplitter contract, with no added functionality, and make that the address OpenSea sends out to. Problem solved?
Deploying a PaymentSplitter solves the accounting task of splitting up royalties, but it still leaves a painful process of pulling funds through a contract with no dedicated UI. Each user has to save the splitter address and use EtherScan to release funds. Unfortunately, checking on EtherScan whether you have funds to release in the first place is a nightmare task that requires:
- Looking up the address of every payee
- Looking up the payout ratio of each payee
- Looking up how much Eth has already been released to each payee
- A bunch of very exciting math
Now imagine you’re an artist that’s worked on 5 different NFT projects, are expecting royalties in this way, and you have to keep track of all that. Not a lot of fun. Realistically, you’d like a single service website that can show you all of your available royalties from the projects you’ve worked on. I, personally, love simple “send me money” buttons.
To solve this problem, we are introducing PaymentSplitter.io. This utility allows you to easily create and keep track of payment splitters. Cloning existing on-chain code dramatically reduces the cost of deploying new payment splitters, and logging all splitters in a central registry makes it quick and easy for users to find the splitters pointing to their addresses.
The current pricing for a payment splitter is 0.01 ETH, and we didn’t pull this number out of thin air. The amount of gas saved using a clone of an existing splitter implementation is roughly 300,000. At 50gwei, that’s 0.015 ETH, so using payment splitter will save you money on deployment as long as gas prices are above that threshold.
Use cases:
- NFT drops
- OpenSea royalties
- Any project with multiple independent contributors
Why you should use it:
- Adding a copy of payment splitter into your existing contract increases contract size. This pushes you up towards the contract size limit, reduces free space for business logic, and increases gas deploy costs. Instead of paying to redeploy this simple logic, why not use an existing on-chain template?
- Adding payment splitter into your existing contract is difficult for untrained operator to use to get their payout
Sometimes you want to securely split funds, but you can only give one address (i.e. OpenSea royalty payouts), and existing solutions (a multi sig wallet) require coordination. - If you have multiple streams of income from many different projects, each with their own payout mechanism, it can become difficult to manage
The payment splitter implementation we started with comes from OpenZeppelin’s contract library. We have made it cloneable and added in a handful of view functions to help with off chain reporting, but beyond that we have not changed the functional properties of the contract. The cloneable pattern we follow comes from EIP-1167.
Cloneable contracts cannot use arguments in their constructors. The existing OpenZeppelin contract uses the constructor to initialize the splitter; we have moved this initialization into a separate function.
Each new splitter created through the manager is registered in the contract, which keeps a record of which payment splitters are pointed at which accounts, allowing for quick lookup of existing splitters.
In V1 of PaymentSplitterManager, there are a few limitations:
- Non-upgradeable. For the sake of quickly developing a version 1, we have forsaken upgradeability in both the manager and the template contract.
- Cannot handle ERC20 tokens. Any ERC20 tokens sent to a splitter will be lost.
- Cannot handle ERC721 tokens. If implemented properly, safeTransfer will revert, as the splitters do not implement onERC721Recieved. Otherwise, any ERC721 tokens sent to a splitter will be lost. Additionally, we ask: how does one split up a non-fungible good?
We hope this tool will help artists and creators save gas on deployment, organize royalties, and route payments effectively. We can’t wait to hear your thoughts and we’re looking forward to feedback on how we can improve this tool in the future. Set up a PaymentSplitter today!
Ethereum Mainnet: paymentsplitter.io
Mainnet Verified Contract: 0x965D0952ad0DaA235Eb0dba933A061d288EDae9a
Ropsten Testnet: rospsten.paymentsplitter.io
Ropsten Verified Contract: 0x613b182cb560380FfeC2Ff903C8155f8502Bd006