6

In the Tron contract (a large ICO listed on many exchanges) lies this modifier which is used for all token transfers :

modifier validAddress {
    assert(0x0 != msg.sender);
    _;
}

I understand how a contract can write directly into the ledger that a token transfer is made from 0x0000000000000000000000000000000000000000, but in that case, the msg is still tied to a an existing contract or private key.
What does this means ? How msg.sender can be equal to 0 ? (excepted the hypothetical case where a keccak256 hash collision is found)

Or could it be because of https://github.com/ethereum/EIPs/blob/master/EIPS/eip-86.md#specification ? If yes, how to withdraw other unprotected ERC20 from the 0x0 ethereum account on next fork ?

  • It’s hard to believe that such serious project similar to EOS listed on more than 50 centralized large volume exchanges and a volume over 200000000$ per day would have left useless code. – user2284570 Jun 6 '18 at 18:05
  • Developper address is mailto:service@tron.network – user2284570 Jun 9 '18 at 21:30
  • Your question do not discuss any (future) EIP86 implementation. You asked about TRON contract, a contract by the way compiled using an ancient version of solidity and by the way copied from other at the time existing contracts. We tried to explain you what was the meaning of that check in a contract, if you need to discuss EIP86 make it directly there and/or ask here about it. Do not change the question using comments!!! – Rick Park Sep 13 '18 at 11:43
  • @RickPark it’s linked : if ᴇɪᴘ86 does what I’m thinking, then it’s obvious that Tron developpers implemented this check for future versions of Ethereum in order to avoid destroyed funds being reused in the future. – user2284570 Sep 14 '18 at 12:03
  • You are out of the truth: they use ASSERT and this means that the instruction is NOT a filter for bad data, but a runtime check only. You were right in case of “require(msg.sender != 0x0)”. Are you a Solidity programmer? You should know this – Rick Park Sep 14 '18 at 13:25
9

Firstly, they're using an assert(), not a revert().

From the docs:

The assert function should only be used to test for internal errors,

And:

Properly functioning code should never reach a failing assert statement; if this happens there is a bug in your contract which you should fix.

See: Difference between require and assert and the difference between revert and throw

Which describes using assert() to "...avoid conditions which should never, ever be possible."

You would need to ask the developers what internal errors they were expecting when they developed and tested the code.


How msg.sender can be equal to 0 ?

Having said all this, address 0x0 is a perfectly valid address. It's just as possible that you'll find the private key to this address as to any other address. If someone does find the associated private key, yes, they'll be very rich, given this address's use as a burn address. (There's a small caveat: not all addresses have associated private keys, given the way addresses are generated. There's no way to know whether address 0x0 is one of these addresses.)

This would mean that the potential owner of 0x0 wouldn't be able to use the Tron contract, which would be a shame... I imagine there are other contracts that have the same check.

It’s hard to believe that such serious project similar to EOS listed on more than 50 centralized large volume exchanges and a volume over 200000000$ per day would have left useless code.

For me that's very easy to believe. The code is essentially copied. When you copy someone's code, you're doing so because you believe it's more transparent than writing your own, while also taking less effort. You make various assumptions, one of which is that the original developers knew what they were doing. If you know the code is already working for someone else, you leave it alone. And yes, that's potentially one way to end up inheriting dead code.

  • You would need to ask the developers what internal errors they were expecting when they developed and tested the code.. Makes sense, but they aren’t replying. A quick look at burn() in the contract shows burning consists of sending to 0x0. Ethereum rely on the impossibility to find a keccak256 collision for a specific address which includes the 0x0 address. – user2284570 Jun 7 '18 at 7:28
  • I don't think there's anything in the protocol or client implementations (or the documentation) that makes the assumption that 0x0 is a reserved address. People have used it as a burn address presumably because it acts as a Schelling Point for getting rid of Ether. The assumption that the community (not the protocol developers) are making is that it's just as unlikely (but not impossible) that someone will find the private key to address 0x0 as any other address they chose to use as a burn address. – Richard Horrocks Jun 7 '18 at 7:37
  • Yes… I agree that 0x0 is not specific. Like most addresses, there’s no private key associated. So you still didn’t described how msg.sender can be null. – user2284570 Jun 7 '18 at 14:45
  • It's possible someone has already found the private key to address 0x0. There's no way of knowing until they make a transaction from the address. Likewise, because key generation is done completely offline - a private key is just any 256 random bits - there's no way of knowing if the private keys of all other addresses have been "found"/generated. This is orthogonal to your original question: the assert() is (presumably) checking for an internal error, not whether someone is genuinely transacting from 0x0. – Richard Horrocks Jun 8 '18 at 8:33
  • 1
    @goodvibration - Agreed. I've edited my answer. – Richard Horrocks Sep 14 '18 at 15:29
-1

It's just a validation that is recommended to do, ethereum and its tool for accessing smart contracts are constantly under development, and that opens the possibility of sending certain data empty or null, and something as serious as an ICO has to cover its back by over validating input data.

As a backend software developer you have to start from the premise that every frontend, mobile or any client can a will send corrupted or malicious data, and is your responsibility to keep your data save, correct and coherent.

  • For me there’s no point in doing so : msg.sender cannot be null. Except if I missed something… Ethereum is no longer a software : they are several independent libraries and programs for handling the whole blockchain interactions. So unless a hard fork introduce 0x0 address access, a change in a program allowing 0x0 handling won’t be recognized by most mining pools. – user2284570 Jun 6 '18 at 18:37
  • Address 0x0 is a valid address, which someone may or may not currently hold the private key to. I don't believe there's anything in the client implementations that prevents it being used. – Richard Horrocks Jun 7 '18 at 7:02
  • @RichardHorrocks : if someone can find a keccak256 collision for 0x0, then I think the whole Ethereum is broken : the point is you can’t choose deterministicly your Ethereum address : if not, it would be the door to emptying all accounts. – user2284570 Jun 7 '18 at 7:24
  • No, of course you can't deterministically choose the address your private key maps to. But if I'm generating a single private key, there's the same chance that it maps to 0x0 as to any other (single) address. – Richard Horrocks Jun 7 '18 at 7:28
  • 1
    @RichardHorrocks no it cannot happen at random in practice. – user2284570 Jun 8 '18 at 10:13
-2

It simply try to trap internal errors causing invalid parameters loading on the stack. The “null pointer” reference is a frequent consequence of stack or dereference problems. Nothing guarantees you that your internal error will result in a null pointer call, but it is quite frequent because uninitialized memory is often zeroed.

That can even be “at least let’s try to avoid that some unpredictable internal error burns coins, please, and if you catch any null pointer around here, quit and revert”

In other words if on one side it is not given that any internal error bring you to a null pointer temptative of use, on the other side it is given that if you have a null pointer here, something is wrong.

Someone is concerning about the fact that the msg.sender address is obtained directly from a EVM call code, namely 0x33, and that being so it cannot be returned wrong.

In order to explain it better: Let’s say I call the 0x33 EVM callcode “CALLER” in order to obtain msg.sender address. Where do I push it in order to compare it with zero? If you answer you will find a first possible area of local corruption, that can be corrupted both writing wrong data in it and in the pointers used to manage it locally: the stack.

if your system is corrupted you can be writing, for instance, the 0x33 return data in some no safe area, where no memory do exist or where it is not writable by your process and you will read it back as 0x0 or other crazy things if you are not able to revert for this. And if the system is corrupted the revert propagation is not guaranteed.

Btw: go on etherscan and look at 0x000...000 address. Is it a valid address to you? Did you think it has been filled with so much ether for a precise willing or for users/code errors?

Furthermore (from a comment): The stack is addressed by the stackpointer, that is a local memory address maintained in a “register”. When you push or pop the “cpu” reference that and increment it in order to point to next slot, decrement if pop.If you have a corrupted stackpointer you will push the value somewhere not known, and when you will pop you will read that somewhere memory location. If you encounter standard ram, nothing happens in that instant... If you think to write (push) where no memory exists or where you are not allowed to read or write, you will read back (pop) 0x0. Ever. This is a canonical example.

  • msg.sender isn’t a parameter so your answer is wrong ! What about ᴇɪᴘ86 : If the signature of a transaction is (CHAIN_ID, 0, 0) (ie. r = s = 0, v = CHAIN_ID), then treat it as valid and set the sender address to NULL_SENDER ? – user2284570 Sep 12 '18 at 13:26
  • you are wrong! the point here is not to measure msg.sender, ma to avoid that, if some corruption wrote wrong data to the pointer and addressing msg.sender bring you to an erroneus 0x0, you will treat that value as valid, making unreversable operation using it, like a trasfer to msg.sender that shall result in a transfer to 0x0... did you realize it? We are discussing about a run time error, not about logic and programmation... – Rick Park Sep 12 '18 at 21:04
  • msg.sender isn’t a parameter passed as optional transaction data to contract, but it is interistic of all Ethereum transactions (whether there is a smart contract triggered or not). In fact, it isn’t even in metadata, but determined by miner from ecrecover with transaction signature (so in reality all signatures are valid but you’ll need the private key for having a signature matching a specific contract) It can’t be a memory corruption in the contract since it used directly from the CALLER opcode. The only possible case of corruption is in the miner software (unlikely). – user2284570 Sep 12 '18 at 22:15
  • So this answer is speculative. On the other side, I’m reading if signature data is (CHAIN_ID, 0, 0) that msg.sender shouldn’t be computed but set to NULL instead. I’m also reading the change is scheduled for being implemented next month. So the question is : did I understood ᴇɪᴘ86 correctly for that part ? (though being able to use the ɴᴜʟʟ address isn’t the primary purpose of the ᴇɪᴘ). – user2284570 Sep 12 '18 at 22:19
  • Let’s say I call the 0x33 EVM callcode in order to obtain msg.sender address. Where do you push it in order to compare it with zero? If you answer you will find a first possible area of corruption, that can be corrupted both writing wrong data in it and in the pointers used to manage it: the stack. Can you realize that if your system is corrupted you can write, for instance, the 0x33 return data in some area where no memory do exist or is not writable and you will read it back as 0x0 or other crazy things? If not, I will stop to discuss with you. – Rick Park Sep 13 '18 at 11:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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