This is challenge number 4 from the EthereumHacker.com list of challenges. Before you can tackle any of the challenges, you first have to install and configure Metamask. If you have not already done so, please take a look at the basic configuration instructions at: EthereumHacker Challenge 1 – The Gala NFT

Our fourth challenge – Market Manipulation:

Go to EthereumHacker.com and click on the fourth challenge: “Market Manipulation

Your task:

Set the USD price of the CBDC from the previous challenge to $66.

Here is again the address of the contract: 0x094251c982cb00B1b1E1707D61553E304289D4D8

Solving the challenge:

Below is the code of the CBDC token we already partially discussed in our previous challenge:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

interface ICBDC {
    function addOracle(string calldata _secret) external;
    function updatePrice(bytes32 _blockHash, uint256 _usdPrice) external;

    function usdPrice() external view returns(uint);
}

contract SetCBDCTo66 {

    address public CBDCContractAddress = 0x094251c982cb00B1b1E1707D61553E304289D4D8;
    
    function updateCBDCPrice() public  {
        ICBDC(CBDCContractAddress).addOracle("bank");

        uint256 blockNumber = block.number - 1;       
        bytes32 blockHash = blockhash(blockNumber);

        ICBDC(CBDCContractAddress).updatePrice(blockHash, 0);
    }

    function getUSDPrice() public view returns(uint)  {        
        return ICBDC(CBDCContractAddress).usdPrice();
    }
}
Our goal is to call the “updatePrice” function and to set the usdPrice to 0

The function contains 2 require statement:

  • The first verifies if the caller (msg.sender) is in the oracles list
  • The second verifies if the provided hash is equal to the hash of the previous block

We already solved the first part in our last challenge. For the second part, we have to create a smart contract that calculates the hash of the previous block and with that information, we can call the “updatePrice” function on the CBDC contract.

Open Remix and create the following file in the “contracts” folder: MarketManipulation.sol

There is no other way around, because a new block is added to the Ethereum blockchain about 11 seconds, which means the blockhash changes every 11 seconds. This makes it complicated to calculate the correct blockhash and to call the “updatePrice” function manually on the Etherscan interface.

So, how can we accomplish that?

We need to call 2 functions on the CDBC contract: addOracle and updatePrice

To accomplish that, we add an interface (ICBDC) to our MarketManipulation.sol file that contains the declaration for the 2 methods mentioned above. We also add the declaration for the “usdPrice” getter function, so we can verify if the usdPrice value was changed successfully.

Then, we create our contract – let’s call it: “SetCBDCTo66“. We add a public state variable (CBDCContractAddress) and assign the address of our CBDC contract:

0x094251c982cb00B1b1E1707D61553E304289D4D8

Next, we create the function (updateCDBCPrice) that will update the usdPrice of the CBDC contract. First, we call the “addOracle” function on the CBDC contract with the correct secret. Then, we get the blockhash of the previous block, using the “blockhash” function.

And, finally, we call the “updatePrice” function on the CBDC contract. To call any of the functions specified in our interface, we need cast the CBDC contract address to that interface.

And, that’s it. You can now deploy the SetCBDCTo66 contract from Remix to the Goerli network using the injected provider from MetaMask (as we already did in Challenge 2) and call the “updateCBDCPrice” method.

To make sure, everything worked, call the “usdPrice” method on Etherscan and verify if it returns the value 66: https://goerli.etherscan.io/address/0x094251c982cb00B1b1E1707D61553E304289D4D8#readContract