Showcasing Sablier: Real-Time Finance

Hey everyone, my friend & colleague @razgraf and I created Sablier. We call it “the protocol for real-time finance”.

How it Works

Say Alice wants to pay Bob a salary worth 3,000 DAI over 30 days:

  1. Alice locks-up the salary in Sablier and sets the “streaming” duration to 30 days
  2. After 1 second, the contract will “stream” a tiny amount of DAI to Bob (around 0.0011574074 DAI)
  3. After 1 day, the contract will stream 100 DAI to Bob, the remaining 2,900 DAI still belonging to Alice
  4. After 5 days, the contract will stream 500 DAI to Bob, the remaining 2,500 DAI still belonging to Alice
  5. At the end, Bob receives the 3,000 DAI, *if* Alice hasn’t cancelled the payment

See this short video for a demo.

Why it matters

The salary use case from above is just one example, as Sablier is actually a new financial primitive that makes the passage of time itself the trust-binding mechanism.

Sablier establishes trust between strangers in ways that hadn’t been possible before:

  • Freelancing
  • Mentoring
  • UBI payouts
  • Rent
  • Lending
  • Insurance
  • Subscriptions
  • Parking lots

How we use OpenZeppelin

Sablier.sol (money streaming engine)

import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/utils/ReentrancyGuard.sol";

Payroll.sol (dapp proxy)

import "@openzeppelin/contracts-ethereum-package/contracts/GSN/bouncers/GSNBouncerSignature.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/GSN/GSNRecipient.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/upgrades/contracts/Initializable.sol";

Gas Station Network

In Payroll.sol, we implemented the acceptRelayedCall function, so that we can subsidise the gas costs for our premium plan users.


Some of our contracts inherit from Initializable.sol, but right before the launch we decided not to make the contracts upgradeable. We’re a small startup and can’t afford the responsibility that inexorably comes with the power of upgradeability.


We also forked Ownable, Pausable and PauserRoler and removed the renounce function, as per the discussion in Contract request: Ownable without `renounceOwnership`.


If you have any questions, ideas, or issues, ping us on one of the channels below. We’d love to hear from you.


Congratulations @PaulRBerg and @razgraf on the launch of Sablier.

Thank you for sharing, great to see insights of how you used OpenZeppelin open source.
Also to hear your thoughts on upgradeability.

I :heart: that Sablier works on mobile too.

1 Like

Thank you! Making dapps responsive is actually harder than I initially expected. You have to account for all the different wallets out there, some of which have different ways to provide you the web3 object… anyways, happy it works now :sweat_smile:


Great to see the transparency:

1 Like

Thanks, @abcoathup! Knowing how Ownable and Pausable work is key to understanding this latest post from Sablier :slight_smile:

1 Like