ethereum / EIPs

The Ethereum Improvement Proposal repository

Home Page:https://eips.ethereum.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ERC 2000: Escrow Token Standard

StartfundInc opened this issue · comments


eip: 2000
title: Escrow Token Standard
author: dev@startfund.io
type: Standards Track
category: ERC
status: Draft
created: 2022-08-16


Simple Summary

A standard interface for Escrow Token.

Abstract

The value of a token can be the total sum of the linked currency’s value. For example, in the Token issuing process, the issuer can receive money from buyers( or investors) and transfer issuing token to buyers. . If the offering process is completed, there is no issue. But buyers can change their plan, or the offering is failed(or be canceled) cause of misfitting the compliance rules or other rules. There is no way guarantee to pay back (refund) to the buyer in the on-chain network.
We have suggested this process make possible in on-chain network with a payable currency like token(ex: USDT)

Motivation

A standard interface allows the payable token contract to interact with ERC-2000 interface within smart contracts.

Any payable token contract call ERC-2000 interface to exchange with issuing token based on constraint built in ERC-2000 smart contract to validate transactions.

Note: Refund is only available in certain conditions(ex: period, oracle value, etc) based on implementations.

Requirements

Exchanging tokens requires having an escrow like the standard way in the on-chain network.

The following stand interfaces should be provided on ERC-2000 interface.

  • MUST support querying texted-based compliance for transactions. ex: period, max number of buyers, minimum and maximum tokens to hold, refund period, etc.
  • exchange(or purchase) with success or failed return code.
  • refund(or cancel the transaction) with a success or failed return code.
  • withdraw when the escrow process has been a success.

Specification

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

There are 3 contracts for the escrow process: Buyer Contract, Seller Contract and Escrow Contract.

  • Buyer Contract: Buyers will pay to an escrow account to exchange with Seller Token.
  • Seller Contract: The seller will pay to the escrow account to exchange with Buyer Token.
  • Escrow Contract: Will be created by the seller. Agent to co-operate between buyers and sellers based on constraint rules. Instead of a simple address mapped balance variable in ERC20 tokens, this balance should have (Seller, Buyer).

Every ERC-2000 compliant contract must implement the ERC2000 interfaces

pragma solidity ^0.4.20;

/// @title ERC-2000 Escrow Token Standard

interface ERC2000 {

    /// @notice escrow balance of owner
    /// @dev assigned to the zero address are considered invalid, and this
    ///   function throws for queries about the zero address.
    ///   in case of escrow contract,
    ///       recommend return buyer's token balance.
    ///       used for backward compatibility with ERC20 standard.
    /// @param
    ///   - _owner: An address for whom to query the balance
    /// @return amount of current escrow account balance. can be seller's token or buyer's token
    function balanceOf(address account) public view returns (uint256);


    /// @notice escrow balance of owner
    /// @dev assigned to the zero address are considered invalid, and this
    ///   function throws for queries about the zero address.
    /// @param
    ///   - _owner: An address for whom to query the balance
    /// @return amount of current escrow account balance. First is buyer token , and seconds is seller token
    function escrowBalanceOf(address account) public view returns (uint256, uint256);


    /// @notice simple query to return simple description of compliance.
    /// @dev must implemented in Escrow-Contract and optional for other contracts.
    function escrowComplianceDescription() external view returns (string);

    /// simple query to return string based on error code. if code is zero, return can be 'success'
    /// @dev must implemented in Escrow-Contract and optional for other contracts.
    function escrowErrorCodeDescription(uint32 _code) external view returns (string);


    /// @notice deposit fund(token) into escrow account.
    /// @dev
    ///   - seller/buyer contract should call escrow contract's function before _transfer.
    ///   - escrow contract should update (Seller, Buyer) balance.
    ///   - seller can call this function to fund initial supply.
    /// @param
    ///   - to:
    ///     In case of buyer/seller contract, must be escrow contract address.
    ///     In case of escrow contract, must be user address who is triggered this transaction.
    ///   - _valuePayed: payable token amount
    /// @return reason code. 0 is success, otherwise is failure code.
    function escrowFund(address to, uint256 amount) public returns (uint32);


    /// @notice refund from escrow account.
    /// @dev
    ///   - seller/buyer contract should call escrow contract's function before _transfer.
    ///   - escrow contract should update (Seller, Buyer) balance.
    ///   - seller should not call this function.
    /// @param
    ///   - to:
    ///     In case of buyer/seller contract, must be escrow contract address.
    ///     In case of escrow contract, must be user address who is triggered this transaction.
    ///   - _valuePayed: payable token amount
    /// @return reason code. 0 is success, otherwise is failure code.
    function escrowRefund(address to, uint256 amount) public returns (uint32);

    /// @notice withdraw token from escrow account.
    /// @dev
    ///   - must implemented in Escrow-Contract and optional for other contracts.
    ///   - buyer is only available when escrow is success, otherwise should call escrowRefund.
    ///   - in case of escrow failed, seller can refund seller-token.
    ///   - if escrow is success, seller and buyer can get exchanged token on their own wallet.
    /// @return reason code. 0 is success, otherwise is failure code.
    function escrowWithdraw() public returns (uint32);

}

Rationale

The standard proposes interfaces on top of the ERC-20 standard.
Each function should include constraint check logic.
In escrow-contract, should implemented internal constraint logic such as period, maximum investors, etc.
The buyer-contract and seller-contract should not have constraint rules.

Let's discuss the following functions.

  1. constructor

An escrow contract will define success/failure conditions. It means constraint rules might not be changed forever (might be changed after being created for the market exchange rate.), so it guarantees escrow policy.

  1. escrowFund

This function should run differently for buyers and sellers.

[Seller]

  • The seller calls this function to be escrow-ready. Seller's token ownership(balance) will be transferred to escrow-contract and the escrow balance will be (Seller: amount, Buyer: 0).
  • The seller can call this function multiple times depending on implementation, but preferred just one time.
    [buyer]
  • When escrow is running (not successful or failed), the buyer can call this function to deposit funds into the escrow account.
  • The escrow balance will be (Seller: amount x exchange-rate, Buyer: amount). The Buyer: the amount will be used for the refund process.
  • Once it is a success, the seller's escrow balance will be (Seller: -= amount x exchange-rate, Buyer: += amount).
  1. escrowRefund

This function should be invoked by buyers only.
The buyer can call this function in the running state only. In the state of failure or success, could not be a success.
The escrow balances of seller and buyer will be updated reverse way of escrowFund

  1. escrowWithdraw

Buyers and sellers can withdraw tokens from the escrow account to their own account.
The following processes are recommended.

  • Buyer can withdraw in escrow-success state only. Ownership of seller tokens can be transferred to the buyer from escrow-contract. In an escrow-failed state, the buyer should call escrowRefund function.
  • When the seller calls this function in the escrow-success state, remained seller token will be transferred to the seller, and earned buyer's token will be also transferred from escrow-account.
  • In the case of escrow-failed, the seller only gets a refund seller token.

Backwards Compatibility

By design ERC-2000 is fully backward compatible with ERC-20.

Test Cases & Implementations

  1. Seller/Buyer Token example

  2. Escrow contract example

  3. Unit test example.

Security Considerations

Since the external contract(Escrow Contract) will control seller or buyer rights, flaws within the escrow contract directly lead to the standard’s unexpected behavior.

Copyright

Copyright and related rights waived via CC0.

Hi @StartfundInc thank you for your EIP.

  1. Please change ERC number from 2000 to 5470.
  2. Consider use the eip-template.md in which it help you to keep up-to-date to the new editorial rules, such as some preamble fields and sections.
  3. Consider send as a PR rather than an issue. If it is just for starting some EIP ideas, etheruem-magician.org provide a better discussion venue. You can come back create a PR once the brainstorm settle to an idea.

Thanks @xinbenlv
I will make this topic in PR(Pull Request) and based on eip-template.md format.

Can you tell me what is the naming rules for ERC?
You said use 5470, but it is issue numbering. When I make PR, How can I choose the ERC Number?

Thanks

How can I choose the ERC Number?

You don't. Editors assign it.

Thanks @xinbenlv I will make this topic in PR(Pull Request) and based on eip-template.md format.

Can you tell me what is the naming rules for ERC? You said use 5470, but it is issue numbering. When I make PR, How can I choose the ERC Number?

Thanks

@StartfundInc
Thanks for your question.

To put it simply: currently you can use github issue number which is 5470.
We are still in discussion of other way of numbering, but that has not converge to a consensus.
A existing consensus is that a new EIP proposer cannot try to snipe a "good" number but what number is considered a good number is up to debate. IMHO, the rule of thumb is that the value of EIP shall depend on its content, not the number, an EIP proposer shall generally be happy witch whatever number the EIP get.

@xinbenlv

Thanks for your reply.

I will work on PR sections, and close this issue.

Thanks again.