Serious bug hidden in cypherpunk

This bug was discovered by dtf, and in their audit report 1 , the vulnerability was described and rated as severe.

cc4d761638af0453e454ae75441a3b4e.png

Briefly talk about what problems this bug will bring: a punk owner can do things that hurt others and not themselves.

Although it is rare, it does happen from time to time. Otherwise, why would there be such a word?

How a punk master does it:

He transfers his punk to address 0, and the person who currently bids the highest bid for this punk will lose his bidding funds in the contract account because the funds are locked.

Let's take a look at how this bug is implemented in the code.

Note: If you have no concept, it is best to read this article first: " Rules are Code: Interpretation of Cypherpunk Smart Contracts in Human Words "

1. A user enters the bidding through enterBidForPunk. If the highest price is bid, his funds will enter the contract.

In the contract, this code looks like the following (you can ignore it).

//用户对某个punk开始投标,参数是punk编号,调用时要带钱的。函数接受Ether。
    function enterBidForPunk(uint punkIndex) payable {
        if (punkIndex >= 10000) throw;  //punk编号应小于10000
        if (!allPunksAssigned) throw;       //特权派送结束后才可以
        if (punkIndexToAddress[punkIndex] == 0x0) throw;  //该punk必须是有主的,而不是无主的
        if (punkIndexToAddress[punkIndex] == msg.sender) throw;  //该punk的主人不能参与竞标
        if (msg.value == 0) throw;   //投标价格一定要大于0
        Bid existing = punkBids[punkIndex];   //获取目前的投标信息,目的是获取当前最高竞标价
        if (msg.value <= existing.value) throw;   //出的投标价高于当前的最高价时,该投标才成功
        if (existing.value > 0) {//之前投标的人的投标价会返回到它的临时账户中
            // Refund the failing bid
            pendingWithdrawals[existing.bidder] += existing.value;
        }
        punkBids[punkIndex] = Bid(true, punkIndex, msg.sender, msg.value); //更新该punk的投标信息
        PunkBidEntered(punkIndex, msg.value, msg.sender); //公告有人以最高价竞标这个事件
    }

2. The malicious punk master transfers his punk to address 0x0, in fact, this is equivalent to destroying the punk

Why transfer punk to 0x0 will be equivalent to destruction, can you think about it?

Because no one owns the address 0x0, it is impossible to calculate the Ethereum address equal to 0 with current science and technology.

Note: Ethereum address algorithm: Usually, the private key is randomly generated, then the public key is generated, and then the public key is hashed with the Keccak-256 algorithm, and the last 20 bytes in the big-endian order are taken as the Ethereum address.

Transferring a punk to an address without a corresponding private key is equivalent to losing it, so it is called burn.

And the code of the cypherpunk does not say that it cannot be transferred to the 0x0 address.

In the code below, the line indicated by the arrow completes this action.

This realizes the "harming others without benefiting oneself" 不利己.

// 转移punk给他人,参数:转给谁(to),punk的编号
    function transferPunk(address to, uint punkIndex) {
        if (!allPunksAssigned) throw;   // 必须是特权派送结束才行
        if (punkIndexToAddress[punkIndex] != msg.sender) throw;  //函数调用者必须是punk的主人
        if (punkIndex >= 10000) throw;  // punk编号要大于10000
        if (punksOfferedForSale[punkIndex].isForSale) {  //如果之前主人正在售卖这个punk
            punkNoLongerForSale(punkIndex);  //停止售卖
        }
--->  punkIndexToAddress[punkIndex] = to;  // 记录这个punk归to了
        balanceOf[msg.sender]--;  // 主人拥有数减一
        balanceOf[to]++;   // to的拥有数加一
        Transfer(msg.sender, to, 1);  // 记录punk转移事件,记录转移人、被转移人
        PunkTransfer(msg.sender, to, punkIndex); // 记录punk赠送事件(其他的转移是花钱的)
        // Check for the case where there is a bid from the new owner and refund it.
        // Any other bid can stay in place.
        //查看被转移方是否之前有对该punk进行投标,有则取消,并将其投标的金额放进其临时账户中
        Bid bid = punkBids[punkIndex];
        if (bid.bidder == to) {
            pendingWithdrawals[to] += bid.value;  // 归还投标者在合约中锁定的金额
            punkBids[punkIndex] = Bid(false, punkIndex, 0x0, 0); //清空投标信息
                }
    }

3. Bidding users will not be able to withdraw from the bidding, that is, the money is locked in the contract and can no longer be taken out.

Originally, users could cancel the bid through withdrawBidForPunk and get their own funds back.

Now, look at the arrow in the following code. Since the address corresponding to the punk is 0, this function cannot be executed (throw exits).

Therefore, his funds cannot be returned, and no one can move them.

This is to the detriment of others 损人.

// 投标人可以自行放弃对某个punk的投标,参数:punk编号
    function withdrawBidForPunk(uint punkIndex) {
        if (punkIndex >= 10000) throw;  // punk编号应小于10000
        if (!allPunksAssigned) throw;       // 特权派送结束后才可以做这事         
--->   if (punkIndexToAddress[punkIndex] == 0x0) throw;   // 该punk应该是有主的
        if (punkIndexToAddress[punkIndex] == msg.sender) throw;  //该punk的主人不能干这事
        Bid bid = punkBids[punkIndex];     // 获取当前的投标信息
        if (bid.bidder != msg.sender) throw;  // 如果调用者不是当前最高出价人,退出。
        PunkBidWithdrawn(punkIndex, bid.value, msg.sender); // 公告这个放弃投标事件
        uint amount = bid.value;  // 获取当前投标价(也即最高投标价)
        punkBids[punkIndex] = Bid(false, punkIndex, 0x0, 0); // 清空投标信息
        msg.sender.transfer(amount);  // 将投标资金返还给投标者的以太坊地址
    }

code modification method

In fact, it is very simple, either when the funds are retrieved, the punk is allowed to be unowned; or when the punk is transferred, the transfer to 0x0 is not allowed.

However, the deployed contract cannot be changed again, and if it is changed, it will be redeployed, and the existing data in the old contract also needs to be migrated to the new contract.

This behavior can only be recognized if Larva Labs officially announces it.

the possibility of this happening

I think it's very unlikely.

After all, harming others and not oneself generally occurs when there is resentment against others: even if you lose yourself, you have to make others feel uncomfortable.

How can you say a punk master resents a bidder who doesn't know who it is!

However, in the vast world, there are all kinds of surprises, and anything can happen.

We can assume this situation:

Some people get a punk at a low cost, for example, they initially obtained one through the getPunk interface (with a gas fee).

I looked at it casually, punk No. 6304 is like this, the punk owner has almost no cost, but the bidding price is now (2021.11.11) 870ETH.

However, he wanted to do something big.

What could be his motive for doing this?

1. Through this incident, he wants to remind the world that blockchain coding must pay attention to security. As long as it is code written by humans, there will be loopholes. (What a kind man!)

2. Through this matter, the cypherpunk was greatly attacked, causing its market value to plummet, and then it was bottom-hunting. (Still looking good!)

3. He hated the person who was bidding.

8bbf29abe00713cd3ae7c90b92730815.pngThe current (2021.11.11) highest bid for punk No. 6304

https://www.larvalabs.com/cryptopunks/details/6304

Liability issues

If this happens, who is responsible and what kind of responsibility?

In fact, this is the last thing Larva Labs, the cypherpunk founding company, wants to see. They said on their official website:

“We write code that lives on the blockchain that anyone can use to buy and sell punks with any other person in the world. One of the interesting things about this system is that we no longer control the code that runs the cypherpunks! Once we publish it on the blockchain, it's permanently embedded there and no one can modify it. It's scary for us as developers because we worry about bugs. But not being able to modify the code is very Powerful, it allows users to verify that there are really only 10,000 punks, verify that we cannot steal any of the punks from you, and ensure that what we claim is true. Cypherpunks are created and run on the ethereum network, code in control Ownership. After that, we no longer have creative or ownership control.”

However, it is not easy to convict the punk owner.

First of all, the person who did this bad thing may not be able to catch him.

Secondly, even if he catches him, he can argue that he was just trying to play (or accidentally misses), but he didn't expect to lose his punk, and he didn't expect to hurt others!

Again, he can say that I really want to destroy it, but I don't want to harm anyone. I don't know that this code has loopholes. I haven't read any audit reports, and I haven't read any articles written by Sir Wei!

In the end, he said, I know all these things, but I think "rules are code", I'm playing according to your rules, how can I violate the rules.

Are cypherpunks responsible?

Larva Labs will say, I just wrote a program for everyone to play, I didn’t expect you to pay so much money to play, I am an open source program, I have already said it on github, I follow the MIT agreement, how about the MIT agreement said?

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

The author translates 2 in human words :

THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING ANY WARRANTIES OF MERCHANTABILITY, FITNESS, NON-INFRINGEMENT, OR OTHERWISE. In no event shall the author or copyright holder be liable for any claims for rights, damages, or other liability. Whether these claims arise from contract, tort, or directly or indirectly from the software and circumstances related to the use or operation of the software.

Did you see it, I said it earlier, I am not responsible, don't say it without warning!

postscript

Hope no one actually does this.

Note: If it is not a cypherpunk, but a similar product in our country, the "Network Security Law" and "Network Product Security Vulnerability Management Regulations" must be followed. The person who finds the vulnerability must report the vulnerability in accordance with the regulations. Providers should be held accountable.


  1. CryptoPunks Quick Audit(https://dtf.is/audits/cryptopunks_dtf_assessment.pdf) 

  2. Talking about the spirit of contract from the MIT agreement

Guess you like

Origin blog.csdn.net/vigor2323/article/details/121279890