# Gold NFT

## Idea

Contract bytecode:

{% embed url="<https://goerli.etherscan.io/address/0xe43029d90B47Dd47611BAd91f24F87Bc9a03AEC2#code>" %}

Decompile it:

{% embed url="<https://library.dedaub.com/decompile>" %}

Here is the pseudocode I got:

```solidity
function () public payable { 
    revert();
}

function 0x0daa5703(uint256 varg0, bool varg1) public payable { 
    require(4 + (msg.data.length - 4) - 4 >= 64);
    require(varg0 == varg0);
    require(varg1 == varg1);
    require(msg.sender == address(0x3));
    STORAGE[varg0] = varg1;
}

function read(bytes32 varg0) public payable { 
    require(4 + (msg.data.length - 4) - 4 >= 32);
    require(varg0 == varg0);
    return bool(STORAGE[varg0]);
}

// Note: The function selector is not present in the original solidity code.
// However, we display it for the sake of completeness.

function __function_selector__(bytes4 function_selector) public payable { 
    MEM[64] = 128;
    require(!msg.value);
    if (msg.data.length >= 4) {
        if (0xdaa5703 == function_selector >> 224) {
            0x0daa5703();
        } else if (0x61da1439 == function_selector >> 224) {
            read(bytes32);
        }
    }
    ();
}
```

The `read()` function actually reads from a storage slot and that slot number comes from our input. In the end `bool(STORAGE[varg0])` will cast the content in that storage slot to boolean, anything nonzero suffices. So our objective is to find out a non-zero storage slot.

The other function with selector `0x0daa5703` is a setter with access control: only address(3) can call it.

In etherscan we can find the "Contract Creation" tx `0x88fc0f1dd855405d092fc408c3311e7131477ec201f39344c4f002371c23f81c`. A lesser-known feature is the "State" tab:

<figure><img src="/files/SQR3dx4pU6K22N2iQHjk" alt=""><figcaption></figcaption></figure>

{% embed url="<https://goerli.etherscan.io/tx/0x88fc0f1dd855405d092fc408c3311e7131477ec201f39344c4f002371c23f81c#statechange>" %}

It shows the storage slot `0x23ee4bc3b6ce4736bb2c0004c972ddcbe5c9795964cdd6351dadba79a295f5fe` was updated from 0 to 1 during creation:

<figure><img src="/files/TZYw75CQ1JoiRbUqSXoz" alt=""><figcaption></figcaption></figure>

This is just what we want, so the "password" is just `0x23ee4bc3b6ce4736bb2c0004c972ddcbe5c9795964cdd6351dadba79a295f5fe`.

After that, notice `_safeMint()` has reentrancy problem, so the rest is easy.

## PoC

{% embed url="<https://github.com/ret2basic/QuillCTF-PoC/blob/main/GoldNFT/test/PoC.t.sol>" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ret2basic.gitbook.io/ctfwriteup/web3-ctf/quillctf/gold-nft.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
