UIP: 1
title: Development of UBI v2 with Streaming Features.
author: @santisiri @juanu
status: Phase 2
created: 2021-08-18
conflicts with: None
languages: EN
Simple Summary
The ability to delegate the accrued UBI to a different address will allow pooling of UBI and increase its utility in multiple ways. This UIP will expand the features of the UBI token to include streaming capacity following the guidelines of EIP 1620 (EIP-1620: Money Streaming) and the Sablier implementation (https://github.com/sablierhq/sablier) that led to more robust and simpler code.
Abstract
Today only those addresses that become verified humans on Proof of Humanity get the right to accrue UBI over time. It has been often said that some of the humans receiving UBI would like to donate it to someone else who might need it more or even stream the accrued UBI to a charitable organization. By allowing the addresses receiving UBI to delegate the streamed accrual to different addresses, these actions can be easily taken. This would increase the utility of the UBI token as well, turning into a streamable asset that can unlock new possibilities for UBI.
Implementation
In order to do a secure implementation with road tested code, the UBI smart contract will be expanded implementing the ISablier interface that has been used on mainnet by the Sablier service that acts as a wrapper to stream ERC20 tokens:
/**
* @title ISablier
* @author Sablier
*/
interface ISablier {
/**
* @notice Emits when a stream is successfully created.
*/
event CreateStream(
uint256 indexed streamId,
address indexed sender,
address indexed recipient,
uint256 deposit,
address tokenAddress,
uint256 startTime,
uint256 stopTime
);
/**
* @notice Emits when the recipient of a stream withdraws a portion or all their pro rata share of the stream.
*/
event WithdrawFromStream(uint256 indexed streamId, address indexed recipient, uint256 amount);
/**
* @notice Emits when a stream is successfully cancelled and tokens are transferred back on a pro rata basis.
*/
event CancelStream(
uint256 indexed streamId,
address indexed sender,
address indexed recipient,
uint256 senderBalance,
uint256 recipientBalance
);
function balanceOf(uint256 streamId, address who) external view returns (uint256 balance);
function getStream(uint256 streamId)
external
view
returns (
address sender,
address recipient,
uint256 deposit,
address token,
uint256 startTime,
uint256 stopTime,
uint256 remainingBalance,
uint256 ratePerSecond
);
function createStream(address recipient, uint256 deposit, address tokenAddress, uint256 startTime, uint256 stopTime)
external
returns (uint256 streamId);
function withdrawFromStream(uint256 streamId, uint256 funds) external returns (bool);
function cancelStream(uint256 streamId) external returns (bool);
}
Rather than using an external contract, these features will work natively with the UBI token and use the native streams from Proof of Humanity. Users will be able to:
-
Only Proof of Humanitty verified addresses can initiate a steam.
-
A human can stream a fraction or the entire UBI accrual to a third party address, whether it’s a verified Proof of Humanity address or not.
-
A human can create 1 or many streams, each carrying its own
streamId
. -
A
ubiPerSecond
amount is specified when a stream is created. -
Receiving addresses will be able to
withdrawFromStream
the accrued UBI on a stream at any given time. Withdrawal is mandatory to prevent UBI being sent to addresses that did not consent to a stream. -
The sender will see his/her balance with the discounted UBI being streamed on real time.
After extensive research, we currently have a working version on https://github.com/JuanuMusic/ubi/tree/UIP-1-Sablier — Even though we expect to work on additional tests, we will have a final version once the UIP reaches Phase 3.
These are the current tests for the streaming features of UBI v2:
UBI streams
✓ require fail - Creating stream of UBI per second higher than UBI.accruedPerSecond should fail.
✓ happy path - After creating a stream that starts in the future, human should accrue UBI until stream starts.
✓ require fail - Creating a stream from a non registered account should fail.
✓ require fail - Creating stream to an existing valid stream recipient should fail.
✓ happy path - While stream with full accruedPerSecond delegation is active, human should not accrue any UBI and stream should accrue.
✓ happy path - When human stops being registered, stream should stop accruing.
✓ require fail - Creating a stream from a non registerded human should fail
✓ happy path - Creating a new stream after one has finished should not increment the number of active streams
✓ happy path - Creating a new stream while others are running or pending should increment the number of active streams
✓ happy path - Creating 2 streams with half accruedPerSecond per each should accrue the same value.
✓ happy path - Creating 1 streams with half accruedPerSecond should accrue half for the stream and half for the human.
✓ require fail - Creating 2 overlaping streams that, when overlaped, sum more than the allowed ubiPerSecond should fail
UBI stream withdrawals
✓ happy path - After stream is finished, and recipient withdraws the balance, stream balance should be 0 and recipient balance should be the stream total
✓ happy path - After withdrawing from an active stream, balance should be 0 right after, but keep accruing until the end.
✓ require fail - Withdraw more than the stream balance while its active should fail
✓ require fail - Withdraw more than the stream balance after stream finished should fail
✓ happy path - Withdraw in the middle of stream and after it finished should add the total delegated balance
Interface
Since this implementation will require an interface that helps a user manage the multiple streams his/her account might be involved with, a specific dapp will developed and implemented to facilitate the interaction with the UBI v2 smart contract.
Next Steps
If this proposal reaches Phase-3, we will have a deployed version of the UBI v2 smart contract on Kovan so anyone in the community can interact and test it.