Skip to content

Latest commit

 

History

History
186 lines (126 loc) · 7.24 KB

ERC1620-v2.md

File metadata and controls

186 lines (126 loc) · 7.24 KB

ERC-1620 (Sep 27, 2019)

eip: 1620
title: ERC-1620 Money Streaming
author: Paul Razvan Berg (@PaulRBerg) <[email protected]>
discussions-to: https://github.com/ethereum/EIPs/issues/1620
status: Final
type: Standards Track
category: ERC
created: 2018-11-24
requires: 20

Simple Summary

We define money streaming as continuous payments over a finite period of time. Block timestamps are used as an on-chain proxy for time.

Abstract

The following describes a standard whereby time is measured using block timestamps and streams are mappings in a master contract.

  1. Developer sets up a money streaming contract.
  2. A payer, henceforth referred to as sender, can create a stream by depositing funds in the contract and choosing a streaming duration.
  3. A payee, henceforth referred to as recipient, can withdraw money from the stream based on its continuous solvency. That is, payment * (current block timestamp - starting block timestamp).
  4. The stream can be terminated by either the sender or the recipient.
  5. If the stream ended and has not been terminated, the recipient is entitled to withdraw all the remaining balance.

Motivation

This standardised interface takes a stab at changing the way we think about trust in financial contracts. Thanks to blockchains, payments need not be sent in lumps (as with monthly salaries), as there is less overhead in pay-as-you-go. Money as a function of time would better align incentives in a host of scenarios.

Use Cases

This is just a preliminary list of use cases. There are other interesting ideas left to explore, such as time-dependent disincetivisation, but, for brevity, we have not included them here.

  • Salaries
  • Insurance
  • Subscriptions
  • Consultancies
  • Rent
  • Parking
  • Lending

Sablier is a champion project for this ERC. It is what we call the protocol for real-time finance.

Specification

Structs

The structure of a stream should be as follows:

  • Stream
    • deposit: the amount of money to be streamed
    • ratePerSecond: the number of tokens allocated each second to the recipient
    • remainingBalance: the left in the stream
    • startTime: the unix timestamp for when the stream starts
    • stopTime: the unix timestamp for when the stream stops
    • recipient: the address towards which the money is streamed
    • sender: the address of the party funding the stream
    • tokenAddress: the ERC20 token to use as streaming currency
    • isEntity: indicates whether the stream exists or not
struct Stream {
    uint256 deposit;
    uint256 ratePerSecond;
    uint256 remainingBalance;
    uint256 startTime;
    uint256 stopTime;
    address recipient;
    address sender;
    address tokenAddress;
    bool isEntity;
}

Methods

getStream

Returns the stream object with all its properties.

function getStream(uint256 streamId) view returns (address sender, address recipient, uint256 deposit, address token, uint256 startTime, uint256 stopTime, uint256 remainingBalance, uint256 ratePerSecond)

balanceOf

Returns the real-time balance of the account with address who.

function balanceOf(uint256 streamId, address who) view returns (uint256 balance)

createStream

Creates a new stream funded by msg.sender and paid towards recipient. MUST throw if recipient is the zero address, the contract itself or the caller themselves. MUST throw if startTime is before the current block timestamp. MUST throw if stopTime is before startTime. MUST throw if deposit is not a multiple of the time delta. MUST throw if the contract is not allowed to transfer enough tokens.

Triggers Event: CreateStream

function createStream(address recipient, address deposit, address tokenAddress, uint256 startTime, uint256 stopTime) returns (uint256 streamId)

withdrawFromStream

Withdraws from the contract to the recipient's account.

MUST throw if the caller is not the sender or the recipient. MUST throw if amount exceeds the available balance.

Triggers Event: WithdrawFromStream

function withdrawFromStream(uint256 streamId, uint256 amount) returns (bool success)

cancelStream

Cancels the stream and transfers the tokens back on a pro rata basis.

MUST throw if the caller is not the sender or the recipient.

Triggers Event: CancelStream

function cancelStream(uint256 streamId) returns (bool success)

Events

CreateStream

MUST be triggered when createStream is successfully called.

event CreateStream(uint256 indexed streamId, address indexed sender, address indexed recipient, uint256 deposit, address tokenAddress, uint256 startTime, uint256 stopTime);

WithdrawFromStream

MUST be triggered when withdrawFromStream is successfully called.

event WithdrawFromStream(uint256 indexed streamId, address indexed recipient, uint256 amount);

CancelStream

MUST be triggered when cancelStream is successfully called.

event CancelStream(uint256 indexed streamId, address indexed sender, address indexed recipient, uint256 senderBalance, uint256 recipientBalance);

Rationale

This specification is designed to serve as an entry point to the quirky concept of money as a function of time. Several other designs, including payment channels have been considered, but they were deemed dense in assumptions unnecessary for an initial draft.

Timestamps

Block timestamps are a reasonably secure proxy for time on the blockchain. Although miners handle them, there are game-theoretical incentives to not provide malicious timestamps. Read this thread on StackExchange for more details.

The only dangerous scenario we can think of is when ERC-1620 derived implementations end up making up a significant share of the volume of money transferred on Ethereum. It is possible, although unlikely, that some stream recipients will have an incentive to coax miners in bumping the block timestamps for them to profit. But we posit the payoff (a few seconds or minutes times the payment rate) will not be high enough for this kind of attack to be worth it.

Implementation

Additional References

Copyright

Copyright and related rights waived via CC0.