Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ERC : Sellable Contracts #798

Closed
pabloruiz55 opened this issue Dec 13, 2017 · 11 comments
Closed

ERC : Sellable Contracts #798

pabloruiz55 opened this issue Dec 13, 2017 · 11 comments
Labels

Comments

@pabloruiz55
Copy link

pabloruiz55 commented Dec 13, 2017

Preamble

EIP: <to be assigned>
Title: Sellable Contracts
Author: Pablo Ruiz <me@pabloruiz.co>
Type: Standard Track
Category: ERC
Status: Draft
Created: 2017-12-12

Simple Summary

The Sellable Contract protocol allows contracts to be sold in exchange of ether.

Abstract

The following discusses a protocol for smart contracts that can be sold by their owners.
User A offers User B the ownership of his contract. User B accepts the offer by sending the arranged sum of ether. By sending the specified sum of ether, User B agrees to buy the contract and becomes the new owner.
Alternatively, User A may put the contract for sale at a certain asking price. Any other account may buy the contract from them on a first-come, first-serve basis.

Motivation

Given that there is no concept of "whoever deploys a contract owns it" in Ethereum, but it's very common for contracts to be assigned an owner upon initialization, there should be mechanisms in place to allow ownership to change hands. This ERC proposes the implementation of a secure transfer of ownership made in exchange of ether.
Such protocol could allow, among other things, for a "smart contract marketplace" or be used by contractors so they can be certain that the code they deploy on behalf of someone else will be paid for when they relinquish ownership.

Specification

Sellable

NOTE: The contract inheriting the Sellable base contract must enforce the usage of the onlyOwner modifier. Owning a contract means having owner set to your account address.

Methods

owner

Returns the current owner of the contract. The owner is the EOA or other contract that can execute key functions of the contract.

function owner() view returns (address owner);

selling

Returns whether or not the contract is being sold. A contract currently being sold might block certain functions until the transaction is completed or canceled by applying the ifNotLocked modifier.

function selling() view returns (bool selling);

sellingTo

Returns the address set by the seller, if they specified a particular target buyer when putting the contract for sale.

OPTIONAL - When putting the contract for sale, this variable can be set to 0x0. In this case, anyone might be able to buy the contract in a first-come, first-serve basis.

function sellingTo() view returns (address sellingTo);

askingPrice

Returns the price at which the contract has been offered for sale.

function askingPrice() view returns (uint askingPrice);

initiateSale

Puts the contract for sale. Only allowed to the owner of the contract, they set an asking price for the contract and (optionally) set a target buyer.
It MUST throw if the contract is already being sold.
It MUST throw if the target buyer is itself or the owner.

NOTE: The asking price can be 0, in the case the owner wants to give the contract away for free or "donate" it.

NOTE: address _to is optional. It can be 0x0, in which case, any other account will be able to buy it.

function initiateSale(uint _price, address _to) onlyOwner public

cancelSale

Cancels the sale of the contract. Resets all the sale parameters. Only available to the owner of the contract.

function cancelSale() onlyOwner public

completeSale

Completes the sale by having a buyer transfer the ether being asked by the seller and changing ownership of the contract. MUST fire Transfer event.
Called by the sellingTo account if specified or anyone other than the contract itself/owner if sellingTo was not specified.
Value sent MUST match the askingPrice.

function completeSale() public payable

Events

Transfer

MUST be fired when a sale is completed. Keeps a history of who the previous and new owners are, as well as the sale date and sale price. It also MUST be fired when the contract is created (with _from being 0x0 and salePrice being 0).

event Transfer(uint _saleDate, address _from, address _to, uint _salePrice);

Modifiers

onlyOwner

MUST be implemented in functions that should only be executed by the owner of the contract.

modifier onlyOwner

ifNotLocked

MUST be implemented in functions that should only be executed while the contract is not for sale.
Implementing this modifier would give the buyers the certainty that key contract values are not being modified while they analyze the purchase.

modifier ifNotLocked

Rationale

The rationale behind this is allowing owners of a particular contract to sell them with the certainty they will receive the asking price at the same time the contract changes hands.
This protocol could also allow for a contract marketplace to be created, where developers can deploy specific contracts and put them for sale.

  • Allowing donations: The contract can be sold for 0 ether if the owner wishes so. This can be useful if the owner wants to gift/donate/give away the contract to someone in particular or whoever gets it first.

  • Allowing contracts with a balance to be put for sale: I'm putting this up for discussion. Right now whether or not the contract has some balance in it is not important, but maybe initiateSale() SHOULD throw if it has some balance to prevent selling a contract that held money inadvertently.

Implementation

Example implementation:
https://github.com/pabloruiz55/Saleable/blob/master/Sellable.sol

Copyright

Copyright and related rights waived via CC0.

@shrugs
Copy link

shrugs commented Dec 13, 2017

Might be worth architecting this as a [The Contract] -> [Ownership Auction Contract] situation, where TheContract has a spec something like

startAuction (address _auctionContract) onlyOwner {}
transferOwnershipFromAuction (address _to) onlyAuctionContract {}

and the auction contract handles all of the bidding/whatever using whatever model people want (DutchAuction, FirstPriceAction, DutchAuction, EnglishAuction, FirstComeFirstServeAuction) and then calls transferOwnershipFromAuction to transferOwnership.

@pabloruiz55
Copy link
Author

@shrugs Yes, sounds like a nice add-on, and I thought about that while working on the implementation example, but I left it out from here as I am not sure if it would be better to make it into a separate EIP. Something like an Auctionable Contract.

@shrugs
Copy link

shrugs commented Dec 13, 2017

I'm not sure combining the auction logic with the contract you're selling is desirable; deploy costs will be high (and unnecessary if you never auction it), it makes it impossible to change the auction structure later (maybe it's first-come-first-serve first, but the new owner runs a dutch auction). You could inline the auction creation logic (so a function like startAuction () onlyOwner returns (address) { auction = new DutchAuction(); return auction.address; }) if you don't want the auction type/parameters to be changeable.

@aunyks
Copy link

aunyks commented Dec 18, 2017

I recommend renaming the title of this ERC to Saleable Sellable Contracts

@pabloruiz55
Copy link
Author

@aunyks I don't mind renaming it although according to what I found online Saleable is as valid as Sellable and even Salable is a possibility.

@3esmit
Copy link
Contributor

3esmit commented Dec 19, 2017

Sellable seems better, I needed to read twice to understand what was about the title, not sure why but at first glance I read it as sealable 🤣

Interesting proposal through, probably useful for decentraland 👍

@pabloruiz55
Copy link
Author

@3esmit Yeah, I'll change the name. Sellable sounds the best. I'll update it shortly.

@pabloruiz55 pabloruiz55 changed the title ERC : Saleable Contracts ERC : Sellable Contracts Dec 20, 2017
@paullizer
Copy link

paullizer commented Dec 25, 2017

Building Ownership transference into Ethereum dramatically improves trust between parties that may have little inherent confidence in each other and ensures a balance of power between individuals during the sale process. I think Pablo's proposal solves the problem.

Sent with GitHawk

@hyperfekt
Copy link

hyperfekt commented Jan 23, 2018

I could imagine that it would be possible to drastically increase compatibility by implementing the ability to own a contract with an ERC #821/#721 registry, and the contract looking its owner up there. (It's probably easiest to just have one global registry with the contract address as asset ID).
We would gain all the work done in different transfer and lookup methods for these, as a smart contract can effectively be seen as a non-fungible token, while at the same time reducing the standard's & implementation's complexity by not needing any sales functionality.

@github-actions
Copy link

There has been no activity on this issue for two months. It will be closed in a week if no further activity occurs. If you would like to move this EIP forward, please respond to any outstanding feedback or add a comment indicating that you have addressed all required feedback and are ready for a review.

@github-actions github-actions bot added the stale label Dec 19, 2021
@github-actions
Copy link

github-actions bot commented Jan 2, 2022

This issue was closed due to inactivity. If you are still pursuing it, feel free to reopen it and respond to any feedback or request a review in a comment.

@github-actions github-actions bot closed this as completed Jan 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants