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

ERC777 Token Standard #777

Open
jbaylina opened this issue Nov 20, 2017 · 499 comments
Open

ERC777 Token Standard #777

jbaylina opened this issue Nov 20, 2017 · 499 comments

Comments

@jbaylina
Copy link
Contributor

@jbaylina jbaylina commented Nov 20, 2017

Please, see https://eips.ethereum.org/EIPS/eip-777 for further discussion.


@tjayrush
Copy link

@tjayrush tjayrush commented Nov 22, 2017

Was there discussion of adding a Mint/Burn pair of events and/or mint/burn functions to this proposed standard?

If this was discussed and rejected, what are the reasons for rejecting it? If it was not discussed, should it have been?

While not foolproof (because a contract may neglect to call these events), it would make the automated accounting of ICO sales for token contracts that do comply a lot easier. To accurately account for existing ERC 20 token sales, one must read and understand the contract's code.

@3esmit
Copy link
Contributor

@3esmit 3esmit commented Nov 30, 2017

What is the use of _to while is obvious that is the TokenFallback reciever itself (the contract address(this)), and why is needed _ref if we can store a _ref data inside _data if application needs it?

I would find better to stick to the needed stuff, such as:

    /**
    * @notice ERC223 and ERC667 Token fallback 
    * @param _from sender of token
    * @param _amount value sent
    * @param _data data sent
    **/    
    function tokenFallback(
        address _from,
        uint _amount,
        bytes _data
    )

Can you describe situations where _ref and _to are important, or crucial?

@jbaylina
Copy link
Contributor Author

@jbaylina jbaylina commented Dec 1, 2017

@3esmit The _to is because the proxy that handles the interface for a specific address can be a different contract. Please see EIP #672 .

For the _ref, this should act as a reference, for example a check number, or an invoice number. In general the ref will be set by the operator and the data will be set for the sender and will be the equivalent to the data in an ethereum transaction.

May be a good alternative would be to integrate this 2 parameters in data and define a standard for data This way we would maintain current compatibility with EIP223...

@3esmit
Copy link
Contributor

@3esmit 3esmit commented Dec 2, 2017

I suggest also adding a boolean return to tokenFallback, and token contract require a true return to accept transaction, in order to avoid this scenario: dapperlabs/cryptokitties-bounty#3

@jbaylina
Copy link
Contributor Author

@jbaylina jbaylina commented Dec 2, 2017

@3esmit This is problematic. This function is called after the transfer is done. So returning false would mean to rollback the transfer. This can add a lot of reentrance issues, so I decided that the function ether executes or throws the full transaction.
The nice thing of this standard is that if the tokens a sent via send it eans the the receiver must register the interface in EIP672 way. If not, it fails. Of course you can use the old transfer method for backwards compatibility.

@izqui
Copy link
Contributor

@izqui izqui commented Jan 4, 2018

I propose renaming operatorData to logData to make more explicit that the purpose of that data is no other than being part of a log. The ability of adding context to token transfers is powerful, and the gas hit is minimal when they are not used.

Really like and support this proposal, exactly the vision that made me excited about ERC223 10 months (!!!) ago. We are considering making ERC777 the base standard for all the tokens issued on @aragon!

@onbjerg
Copy link

@onbjerg onbjerg commented Jan 4, 2018

This is an interesting proposal, but I worry about the entire ecosystem having to migrate to new multisig wallets in order to be able to receive ERC777 tokens.

It seems like there was an attempt made to create a whitelist of contracts that one can safely transfer to even if they do not implement ITokenReceipient:

The function MUST throw if:

  • to is a contract that is not prepared to receive tokens. That is it is a contract that does not implements ITokensReceived interface and the hash of the sourcecode is not in between the whitilisted codes listed in the appendix of this code.

But there is no such appendix, I would love to see it 😊

@jbaylina
Copy link
Contributor Author

@jbaylina jbaylina commented Jan 4, 2018

@onbjerg We are working on it. We are thinking in keeping this list open for a while (centralized) and close the list at some point (make it decentralized).

@sohkai
Copy link

@sohkai sohkai commented Jan 4, 2018

Was there any consideration over allowing users to specify how much an operator can control, e.g. changing authorizeOperator() to:

function authorizeOperator(address operator, uint authorizedAmount) public?

One could use 2^256 - 1 (or hypothetically the totalSupply() if that never grows) to simulate the previous true behaviour and 0 for false.


The only difference for new contracts implementing ERC20 is that registration of ITokenRecipient via EIP-672 takes precedence over ERC20. This means that even with on a ERC20 transfer call, the token contract MUST check via EIP-672 if the to address implements tokensReceived and call it if available.

I find this somewhat confusing and unexpected. We'll have a dichotomy of "ERC20" tokens: ones that will never call the tokensReceived() callback, even if ITokenRecipient is registered; and ones that will always check. Even if the ERC20 functions are only supposed to be called via old contracts, I think there'll be lots of confusion about this since the meaning of what an "ERC20" token will have essentially changed depending on if your token also supports EIP777.

It also feels odd because you don't have to support the ERC20 interface with EIP777, but you most likely will to support prior contracts expecting that standard.

What if EIP777 was instead a superset of ERC20's interface but overrided specific parts, e.g. transfer() and transferFrom(), to support the ITokenRecipient interface?


I kind of like and dislike the send() nomenclature. On one hand, it's nice how it parallel's ETH's transfer() and send() nomenclature. On the other, it's confusing because these two terms are now both overloaded with different meanings for ETH and tokens. It's confusing enough that we have both for ETH, but it's going to be even more confusing when there's the same names for tokens. I do like the naming for transferAndCall() because it's really obvious what it's probably going to do.

I guess an alternative could be transferToRecipient().

@jbaylina
Copy link
Contributor Author

@jbaylina jbaylina commented Jan 4, 2018

@sohkai:
1.- The idea o authorizeOperator is mainly to authorise a contract.
The maximum allowed limitation and many others limitations, like a daily limits, should be implemented in the operator contract and keep this standard as clean as possible.

2.- The idea is that the receiver should have the warranty that the tokensReceived() method is ALWAYS called. Even if it is called via an obsolete ERC20 transfer() or transferFrom() method. This way, for example, allows a recipient to NEVER accept a specific token. or forward some tokens to a specific charity.

3.- The big problem of maintaining transfer() name in the new standard is that if you use transfer() in an ERC20 only token, you will end up locking a lot of tokens. This mistake might become very common in a moment where 50% of the tokens are ERC20Only and 50%ERC777.

@MicahZoltu
Copy link
Collaborator

@MicahZoltu MicahZoltu commented Jan 4, 2018

As I have mentioned in other threads, I strongly recommend removing decimals. Here is a cross post of what I have said elsewhere:

Decimals are easily the number one source of confusion for both token authors and users of ERC20. I strongly recommend removing this as a variable and instead asserting that tokens must have a certain "humanizing divisor". Reasonable choices IMO are:

  • 0 - The purpose of decimals is to humanize a very large number, nothing more. If you issue a bunch of your tokens, then people can work with gigatokens instead of tokens. People are used to this already with hard drives (no one talks about hard drive size in bytes, it's gigabytes or terrabytes). This scales with the system and allows it to easily change with time.
  • 10^24 - This Allows the token to center on a range that is maximally within the accepted SI prefixes, ranging all the way from yoctotokens to yottatokens. From a scientific/mathematics standpoint, this is probably the best option.
  • 10^18 - 10^18 is the most common humanizing divisor, and it is what ETH used. In order to limit confusion, there may be value in asserting that everyone should just use this. While this isn't a particularly optimal choice, it is fairly compelling due to ETH choosing it.
  • 10^2 - Most fiat currencies use cents, in general, population is more used to currencies with 2 decimals than 0 or more than 2. I'm including this for completeness, but it ends up being effectively the same as 0.

I think the worst option is to continue to allow for variable humanizing divisors. This doesn't actually solve any real problems, since any chosen unit is very likely to be a wrong choice at some point in time (too big or too small). Also, since the token author can pick the token supply, allowing them to also choose the humanizing divisor doesn't give them any more/less power to try to target a "nice human-scale number".

@MicahZoltu
Copy link
Collaborator

@MicahZoltu MicahZoltu commented Jan 4, 2018

You mention function send(address to, uint256 value, bytes userData, bytes operatorData) public; in the interface but it doesn't appear in the function descriptions below. Perhaps it was meant to be replaced by operatorSend but you forgot to delete it from the interface?

@MicahZoltu
Copy link
Collaborator

@MicahZoltu MicahZoltu commented Jan 4, 2018

I recommend splitting function authorizeOperator(address operator, bool authorized) public; into:

function authorizeOperator(address operator) public;
function revokeOperator(address operator) public;

At the callsite, this will provide a lot more clarity as to what is happening.

@bwheeler96
Copy link

@bwheeler96 bwheeler96 commented Jan 5, 2018

This is rad. Its going to be a long, slow journey to move away from ERC20 but this is a good first step. Couple things:

  1. Why has spender authorization been moved to a boolean? I personally haven't found a use-case for allowing a spender to access a specific amount, but it seems like a nice feature to have since its already part of an existing standard.
  2. Why use the noun operator? I understand this is stupid-picky and certainly hair-splitty, but the work spender is, IMO, a really good descriptor of that particular actor. Operator just sounds like the person has more capability than they do (they aren't really "operating" on the tokens).

Anyways, big 👍. ERC20 needs an upgrade.

@nepalbitcoin
Copy link

@nepalbitcoin nepalbitcoin commented Jan 5, 2018

Public state variable for decimal is string public decimals;?
I think that should be uint8 public decimals; based on function decimals() public constant returns (uint8). Prolly a typo.

@GoldenDave
Copy link

@GoldenDave GoldenDave commented Jan 5, 2018

As I have mentioned in other threads, I strongly recommend removing decimals. Here is a cross post of what I have said elsewhere:

Unfortunately quite a few coins have a very good reason for selecting a different number of decimals. Many of them are in the wild already. Forcing all 10 n decimals would require internal restrictions that would, for example, force rounding of values or revert if an incorrect amount is specified.

Our objective is seldom to expect people to interact directly with the blockchain but, as an example, MEW does a good job of removing the decimal confusion.

@alexvandesande
Copy link

@alexvandesande alexvandesande commented Jan 5, 2018

Should the ITokenRecipient contract also have a function that always returns true stating it's capable of this? It's a way to allow wallet implementers to know which function to use, and therefore save gas.

function isITokenRecipient() returns (bool) { return true};
@lyricalpolymath
Copy link

@lyricalpolymath lyricalpolymath commented Jan 5, 2018

Great stuff!

1- initially I too thought as @sohkai that authorizeOperator() would need a form of limiting the amount. In the end the ERC20 approve (which is a confusing name) does have a value up to which the spender is allowed.

I understand and share what you say

The idea o authorizeOperator is mainly to authorise a contract.
The maximum allowed limitation and many others limitations, like a daily limits, should be implemented in the operator contract and keep this standard as clean as possible

But I also think that it's an interesting addition to remind implementers to include optional limitation logic.


2- operatorSend userData vs operatorData
what is the scenario you are imagining for userData?
in any case it's a data that the operator has to input when calling the operatorSend function. Why couldn't both data points be contained in one?


3- Backwards Compatibility
I also found this a bit confusing

The only difference for new contracts implementing ERC20 is that registration of ITokenRecipient via EIP-672 takes precedence over ERC20. This means that even with on a ERC20 transfer call, the token contract MUST check via EIP-672 if the to address implements tokensReceived and call it if available.

I understand that new smart contracts will detect the right function to call (right?)
but what about users interacting directly with the contract? It will be confusing to see 2 functions that supposedly do more or less the same thing but have different names.
confusing UX and a potential source of problems if you say that "tokens will probably be locked"

@jbaylina
Copy link
Contributor Author

@jbaylina jbaylina commented Jan 5, 2018

@lyricalpolymath
3- New contracts that use new tokens must use send() and not transfer(). transfer() is just for backwards compatibility. mainly old smart contracts, as I expect that UI will be upgraded at some point.
Stay tunned for (1 & 2)

@jbaylina
Copy link
Contributor Author

@jbaylina jbaylina commented Jan 5, 2018

@alexvandesande To know if a contract implements ITokenRecipient, the reverseENS is used (EIP672) which will never throw and you will know if it implements or not the Interface. The gas cost should be the same as the one you propose.

@MicahZoltu
Copy link
Collaborator

@MicahZoltu MicahZoltu commented Jan 5, 2018

@GoldenDave Others have made the same argument in the past but were unable to provide (IMO) a compelling argument as to why forcing the humanizing divisor to the same for all tokens is bad. The most common cited example is "what if I have a token that is pegged to USD (or similar), which only has 2 decimals?" In this case, you can still have 24 decimals (or whatever the standard defines) exposed to the user and the contract can internally store however it likes. In this case, you would simply multiply whatever internal value you have by 10^22 when it is returning to the user. In all cases I have seen people come up with (including the USD peg) nothing is hurt by having a token be more divisible. There is really nothing fundamentally wrong with having 1 attousd.

@alexvandesande
Copy link

@alexvandesande alexvandesande commented Jan 5, 2018

@jbaylina I support reverse ENS, but I don't see why not also add this to the contract itself. Is simpler to build, will work on any network, including test networks etc. Also, to check ens resolver you need to have multiple calls (see if there's a resolver, then check the resolver etc) AND to have an extra function on the constructor function to set the ens resolver info.

Again, I'm all for ENS, but why not add on the contract simple info like that? Reminds me of the debate on either tokens should have symbol and names on the contract or on a token registry: in contract won by the simplicity of it.


Also: I'd like to propose to add a provable standard to this token. One of the most requested features I get from token creators is how to send tokens without having ether and I think it makes sense that should be a core function of whatever is the next big token version.

@DaveAppleton
Copy link

@DaveAppleton DaveAppleton commented Jan 5, 2018

Others have made the same argument in the past but were unable to provide (IMO) a compelling argument as to why forcing the humanizing divisor to the same for all tokens is bad.

During the HelloGold token sale, contributors received HGT which entitled them to a share of a reward token GBT (our gold backed token) which is related to the amount of management fees that we receive for storing clients' gold pro rated to the person's HGT holding.

In order that anybody holding the minimum amount of HGT should receive GBT during a distribution we calculated that GBT would work with 18 decimals but as a result HGT would need to have 8 d.p. Any more precision would be pointless and misleading.

It it rather dictatorial to say that everybody needs to normalise everything to meet a number of decimal points that do not particularly agree with them, especially when we already have a method of handling it.

@DaveAppleton
Copy link

@DaveAppleton DaveAppleton commented Jan 5, 2018

Should the ITokenRecipient contract also have a function that always returns true stating it's capable of this? It's a way to allow wallet implementers to know which function to use, and therefore save gas.

It is great idea - but when I ran a quick test on remix, a contract with a simple fallback function would falsely satisfy your requirements.

function(){
}

appears to return true when a non existent function xyz() returns (bool) is called.

https://gist.github.com/DaveAppleton/ef44e9745b1f57c7ae0d6744a15bc5c6

@jbaylina
Copy link
Contributor Author

@jbaylina jbaylina commented Jan 6, 2018

@alexvandesande One of the nicest think of this standard is that not only you can have functionality in smart contract recipients, but also in any regular account. You can program for examle that you don't accept tokens sent to your public regular account. Or that you send half of it to a charity.
I agree that using EIP672 is a little complicated, and what's the worst, ENS still is centralised in some way. So that is why we plan to use EIP #820 which is equivalent to EIP672 but much more simpler and pure decentralised contract. (It still is a work in progress).

@jbaylina
Copy link
Contributor Author

@jbaylina jbaylina commented Jan 6, 2018

@alexvandesande Regarding the provable functionality, the idea is to do that via an operator. The operator can, for example, accept signed checks, which they are very much provable transfers.

This standard should allow for token contract creators to set some default operators to be authorised for everybody.

@alexvandesande
Copy link

@alexvandesande alexvandesande commented Jan 8, 2018

@DaveAppleton I just tested your code and got

{
	"0": "bool: false"
}

So it seems it should work.

@0xjac
Copy link
Contributor

@0xjac 0xjac commented May 7, 2019

The last call of ERC777 ended yesterday. Therefore I would like to move ERC777 to final.

The last call period was extend by a week, for a total of 3 weeks, to deal with last minute feedback.

There was no significant and no functional changes but mostly clarifications and corrections.
The following changes occurred during the last call period:

  • Cleanup (markdown formatting, code formatting, some terminoloogy)
  • Add interfaces hash literals for ERC1820
  • Add constraint to revert if a hook revert
  • Explicitly prevent minting and burning for 0x0
  • Clarification on compatibility for ERC20 transfer with contract recipients
  • Fixed constraints for movements with amounts of zero
  • Expanded rationale section

Details on the changes during the last call period can be checked at #1945.

A huge thanks to everyone who provided feedback and supported the development of the standard.

@nicksavers , could you please merge #1999 to mark ERC777 as final. Thank you.


@frangio That is correct: ERC777's operators and ERC20's approve/transferFrom are completely independent
and do not affect each other since they are separate standards.

You can have a look at the backward compatibility section for further details:

This EIP does not use transfer and transferFrom and uses send and operatorSend to avoid confusion and mistakes when deciphering which token standard is being used.

Regarding your second point, the SHOULD is correct. The MUST indicated that the table below it has to be respected.
That table says that in the case of a missing tokensReceived hook for a contract recipient transactions using ERC20's transfer or transferFrom should continue.

@guylando
Copy link

@guylando guylando commented May 7, 2019

@0xjac Thanks a lot for your work on ERC777!
Could you please check my comment at #777 (comment) ?
Do you think we (the ethereum community) should start using ERC777 for ICO/IEO/IBO instead of ERC20 (an ERC20 compatible version to be supported to be listed by exchanges)? Maybe you are aware of some token which already started using it?
Thanks!

@0xjac
Copy link
Contributor

@0xjac 0xjac commented May 8, 2019

@guylando Whether you want to use ERC20 or ERC777 is subjective. I believe ERC777 has significant improvements over ERC20, however it is very new and there is almost no support for it yet.

I would (obviously) encourage the Ethereum community to start using ERC777 if it matches their use cases but I would also highly recommend to make any ERC777 token compatible with ERC20.

I am not yet aware of a token implementing the final version of the specs. I had contacts with people behind the "CALL token", they used a now outdated draft of the standard. They are aware of it and I can only hope they will update their token. I also had contacts with other people interested in making ERC777 tokens and I have a backlog of emails related to ERC777 which I have to go through and answer.

edit: I am currently working on the reference implementation and a new version will be released soon

@bluerosss
Copy link

@bluerosss bluerosss commented May 8, 2019

I am not yet aware of a token implementing the final version of the specs. I had contacts with people behind the "CALL token", they used a now outdated draft of the standard. They are aware of it and I can only hope they will update their token. I also had contacts with other people interested in making ERC777 tokens and I have a backlog of emails related to ERC777 which I have to go through and answer.

Hello Jacques,
Yes, GCA (GlobalCryptoAlliance) has implemented CALL token few months ago (which was the first erc777 in the cryptosphere but only for a team use - none offering), we were waiting for the new ERC1820 and Final ERC777 to update and deploy our new smartcontract, and also to spread it in cryptosphere. Thank you very much again (you and Jordi) for the great job and for recent final steps, we believe strongly in this new disruptive standard... Warm regards Jacques,
JC from GCA (GlobalCryptoAlliance) / gcalliance.io

@mcdee
Copy link
Contributor

@mcdee mcdee commented May 8, 2019

Great to see this reach final.

I wrote an article explaining some of the features of ERC-777; it's available at https://www.wealdtech.com/articles/understanding-erc777-token-contracts/ and a companion piece focusing on operators is available at https://www.wealdtech.com/articles/understanding-erc777-token-operator-contracts/

@frangio
Copy link
Contributor

@frangio frangio commented May 8, 2019

We've now finished the OpenZeppelin implementation, including ERC20 compatibility by default.

It's released now in v2.3.0-rc.2: ERC777.sol.

Also available on npm: npm install openzeppelin-solidity@next.

We'll be doing a final internal security review in the coming days before the final 2.3 release. An independent security audit has not been done yet.

@mcdee
Copy link
Contributor

@mcdee mcdee commented May 9, 2019

@frangio any reason the OpenZeppelin implementation hard-codes granularity to 1? It is a variable within the spec.

@frangio
Copy link
Contributor

@frangio frangio commented May 9, 2019

@mcdee Good question. The EIP says the following about granularity:

NOTE: Most tokens SHOULD be fully partition-able. I.e., this function SHOULD return 1 unless there is a good reason for not allowing any fraction of the token.

Keeping this in mind, we decided to go with a hardcoded granularity if 1 for our first release of the ERC. It makes the code simpler to understand, and simpler for people to use, which might help adoption. However, it's very easy to add granularity on top as an extension and we plan to do this once we see some demand for it.

The same applies to opting out of ERC20 compatibility. It's not possible in this first release but we may add it as a feature down the road.

@mcdee
Copy link
Contributor

@mcdee mcdee commented May 9, 2019

@frangio ERC-20 functionality is orthogonal to ERC-777, but granularity is part of the spec. I would urge you to add this before releasing the token.

(This is another good example of why SHOULD is a horrible designator in an ERC).

@guylando
Copy link

@guylando guylando commented May 11, 2019

I posted here some questions on the ERC777 implementation: OpenZeppelin/openzeppelin-contracts#1749
and I see some of those questions (such as 5, 7, 8) are also relevant for the reference implementation https://github.com/0xjac/ERC777/blob/master/contracts/examples/ReferenceToken.sol

@guylando
Copy link

@guylando guylando commented May 13, 2019

Maybe it could be a good idea to somehow contribute to EIP 1155 for it to add built in support to ERC777 like it adds to ERC20 and ERC721: #1155
Otherwise ERC777 and ERC1155 will cause a division among tokens while both providing similar behaviors for a single fungible token.
I was not involved enough in the ERC777 standard creation to be able to do this, however I think it would be good for the Ethereum community if it would happen instead of creating partially duplicate standards.

@AC0DEM0NK3Y
Copy link
Contributor

@AC0DEM0NK3Y AC0DEM0NK3Y commented May 13, 2019

Maybe it could be a good idea to somehow contribute to EIP 1155 for it to add built in support to ERC777 like it adds to ERC20 and ERC721: #1155
Otherwise ERC777 and ERC1155 will cause a division among tokens while both providing similar behaviors for a single fungible token.
I was not involved enough in the ERC777 standard creation to be able to do this, however I think it would be good for the Ethereum community if it would happen instead of creating partially duplicate standards.

ERC1155 does not have in-built support for ERC20 or ERC721 so it does not need to add in ERC777 as a dependency either.
The only standard #1155 depends on is #165.

ERC1155 differs to ERC777 in that it supports multiple token types (if needed) and the possibility of mixing of NFT and FT so they are targeting different scenarios imho.
ERC1155 was primarily devised to support game items as that is the scenario that most needs a mix of fungibility and many different types, for example: https://enjinx.io/eth/assets

@guylando
Copy link

@guylando guylando commented May 13, 2019

  1. ERC1155TokenReceiver seems to be a parallel to ERC777TokensRecipient and the batch abilities of ERC1155 seem relevant for ERC777 as well.
  2. On the other hand the operators idea of ERC777 and the sender hook of ERC777 seem as would enhance ERC1155.
  3. Maybe some would want to be able to manage multiple ERC777 in the same contract like ERC1155 provides.

Even if the idea of ERC1155 is for game items, the implementation has nice things which can contribute to ERC777 and on the other hand ERC777 has nice things which can contribute to ERC1155.
At least so it seems to me. Maybe my wording about "ERC1155 having built in support for ERC20 and ERC721" was wrong but what I meant is that from reading ERC1155 seems the standard implementation had in mind (and mentioned) ERC20 and ERC721 and if it would would have in mind ERC777 maybe the proposed interface would be a bit different (for example would take the operators idea and sender hook).

If the idea of ERC1155 is to ONLY be an encapsulation of adding the ability to hold multiple tokens then it adding batch functions seems to contradict that as those are an enhancement for the tokens and not just part of the ability to hold multiple tokens.

@AC0DEM0NK3Y
Copy link
Contributor

@AC0DEM0NK3Y AC0DEM0NK3Y commented May 14, 2019

erc777 much like erc721 and erc20 does not include the "_id" designation in key functions like balanceOf, so merging them and erc1155 together just isn't going to fit very well.

An example is erc777 uses this signature:

function operatorSend(address from, address to, uint256 amount, bytes calldata data, bytes calldata operatorData)

and erc1155 uses:

function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external;

they both can have "operators" that have permission to move tokens from one spot to another but erc1155 has that specific _id param to also say which type this transfer is attempting to move.

Now if erc777 could introduce some form of type into that signature and all its others, one or the other standard is potentially redundant. The issue is that erc777 has to have backwards compatibility and is designed to be additive to erc20, so I can't see this happening personally but I suppose it is possible.


What is possible also is that the receiver signatures are unified if erc777 was to add in an "_id" param and erc1155 was to add in the "_operatorData" param, but if you are proposing that the receivers are merged (without the entire standards being merged) then there has to be a way to also know "this is an ERC-X token you are receiving" which also necessitates a param to make this a generic solution like a data param that accepts keccak256("ERC1155") and keccak256("ERC777") perhaps so that it may act accordingly based on the type it is receiving (for eg. a contract may be an erc1155 receiver only that may only want to allow acceptance of _id==0x123).
Erc1155 also has batch receiver functions and erc777 does not as it doesn't need them as there is only one type.

It all sounds a little cumbersome/wasteful in usage, and in the logistics of getting two standards over the finish line; Arguably for little benefit when they are seemingly standards designed for different motivations and use cases.

I mean sure, a generic smart wallet that wants to be able to hold and send every standard out there may now have to have two receiver function sets implemented, but even if the receivers are unified they would still have to potentially branch in the logic on the receiver function for the erc type and definitely do on the dapp side with the knowledge the source contract for the send is an impl of a particular standard, so it doesn't really save anything.
A sensible setup to cover this and future additions to any current standard that may occur in a smart wallet is Argent's module based fallback receiver or arguably as is the case with erc777 given the abundance of erc20 impls already out there, usage of erc1820 and possible fallback to "unsafe" transfers.


With respect, instead of coming onto both standards pages and asking us to change things right at the last minute of both the standards being final after months of discussions, if you could propose an actual working solution in a fork that covers both our problem domains I think it would be far more productive. Otherwise I imagine we will both go final fairly soon.

edit: I see after looking through the comments 777 is already final as of a few days ago. Congrats!

@anushreepandya
Copy link

@anushreepandya anushreepandya commented Nov 27, 2019

I need to understand the value that can be passed in data and operatorData parameters of the Send function in ERC777. Can someone brief me about that with an example. I know that it is bytes datatype. My question is about what should be converted to bytes datatype.

Thanks in advance

@fulldecent
Copy link
Contributor

@fulldecent fulldecent commented Nov 27, 2019

This is a finalized EIP. Please open questions like this on Stack Exchange or similar website. You will get great answers there, I promise. You can ping me @fulldecent and I will check it out.

This thread here is for discussing the standard itself and any serious problems with the specification (since it is already final).

@Revinand
Copy link
Contributor

@Revinand Revinand commented Feb 9, 2020

Hello. There is a mistake in the description.

In the first paragraph of ERC777TokensRecipient section (https://eips.ethereum.org/EIPS/eip-777#erc777tokensrecipient-and-the-tokensreceived-hook) ERC777TokensRecipient should be used instead of ERC777TokensSender.

@MicahZoltu
Copy link
Collaborator

@MicahZoltu MicahZoltu commented Feb 9, 2020

@Revinand For non-normative changes (like typo fixes and such) you can just submit a PR against the EIP. Just go to https://github.com/ethereum/EIPs/blob/master/EIPS/eip-777.md and click the little edit pencil at the top right-ish.

@Revinand
Copy link
Contributor

@Revinand Revinand commented Feb 9, 2020

@MicahZoltu Ok, sure. My bad

@yuwiggin
Copy link

@yuwiggin yuwiggin commented Feb 17, 2020

Is ERC777 vulnerable to short address attack? How to avoid it?

@0xjac
Copy link
Contributor

@0xjac 0xjac commented Feb 17, 2020

@Revinand thanks. I saw the PR. I can't merge it but I hope an EIP editor will do it soon.

@yuwiggin short address attack is more of a vulnerability in Solidity itself. There is not much to be done at the standards level.

If you want to protect yourself against short address attack you can always check for the length of msg.data. Note hover that the send methods have bytes parameters. So you can check a minimum length to avoid the attack on operator, holder address, and the amount.

@MicahZoltu
Copy link
Collaborator

@MicahZoltu MicahZoltu commented Feb 17, 2020

Latest version of Solidity has built in checks for incorrect calldata size IIRC.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
You can’t perform that action at this time.