I'm trying to get familiar with the patterns in designing Solidity smart contracts.

For example, say I'm trying to model a Mall with multiple Restaurants in it. Each restaurant can have multiple Owners owning a stake in the restaurant. The person with the greater than 50% ownership is the main owner of the restaurant. Each restaurant has a valuation. People trade ownership of the restaurants using a MALL token.

Show the main model entities: a mall which contains restaurants which are owned by multiple people

Now assume that I have the following user interface.

  • (1) "Bidders" can see a list of owners of a restaurant and can make an offer to buy all or some of an owner's share of the restaurant. They can bid at market value for the share or above/below market value
  • (2) The owner can see various bids and choose to accept/reject the offers.

2 user interfaces for making bids and accepting/rejecting them

With an ERC20 token, you would need to make an allow transaction followed by the actual transaction so I thought using an ERC777 would allow for an easier workflow.

The "Mall" contract could be an "operator" for the "MALL" ERC777 token.

I thought the actual bid making could happen off-chain.

When a bid is accepted, that's when something is written to the blockchain (something that confirms that the owner is willing to sell their share, how much and for what value).

Otherwise I feel it would become too messy - if the bidder had to transfer tokens with each bid, then the owner could purposely not respond to them and tie up the funds of the bidder. Obviously I could use some kind of time calculation. But to revert the funds even with a window for the owner to accept/reject without making it too costly for myself would need some kind of UI/mechanism for the bidder to go retrieve their funds minus fees (which is not a good user experience!)

So in a nutshell I'm stuck trying to figure out what is the best way to write this smart contract without making the user interface too complicated or burdensome on the end user. I feel like this would be something very common in the Solidity world but despite a great deal of searching, I can't find the best practices on how to implement this.

1 Answer 1


I would create a ERC1155 contract for each mall. ERC1155 allow the creation of multiple tokens in a single contract, which is exactly what you need. Each token is distinguished by a token id. I would make the first token (id = 0) the mall token. All other tokens created (id >= 1) will be the restaurants tokens.

Contract must define a SHARE_PRECISION global variable which will represent the number of restaurant tokens minted when creating the restaurant.

You must create a createRestaurant function which takes an array of tuples (address _address, uint256 _proportion), where _address is a restaurant's shareholder and _proportion is a proportion of SHARE_PRECISION. When calling this function all addresses will receive _proportion amount of tokens. The contract must check that sum of all _proportion values in array = SHARE_PRECISION.

To trade restaurant tokens a executeTrade function must be created. The function must take as parameters:

  • the restaurant token id (_id)
  • the amount of restaurant tokens being bought (_amount)
  • the cost in mall tokens (_cost)
  • the seller address (_seller)
  • signature from the seller (_sig)

Signature from the seller is generated by encoding (_id, _amount, _cost) and signing it with _seller. Then this signature is passed off-chain (through your app I suppose) to the buyer.

The buyer then calls the executeTrade() function passing all aforementioned parameters. executeTrade() initially verifies that the signature is valid, ensuring that _id, _amount, _cost and _seller are all legitimate parameters. The contract then verifies that the buyer's mall token balance >= _cost. It then transfers _cost amount of mall token to the _seller. Finally it transfers _amount amount of restaurant token _id from the _seller to the buyer.

The transferFrom function must by overridden in order to:

  • make all tokens whose id >= 1 (restaurant tokens) un-transferable unless when called from createRestaurant() or executeTrade().

Token id = 0 (mall token) will be freely transferable like any other ERC-20 token.

All the bid making process can be dealt with off-chain. As soon as a restaurant owner accepts a bid, he signs a message which is then sent to the buyer. The buyer then executes the transaction. Considering that executeTrade() already verifies the transaction, you can also override the token transfer approval, yet this would require a more in-depth explanation.

Should you need other help, feel free to ask.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.