Skip to content

Latest commit

 

History

History

week2

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 

Week 2

Lesson 1

Q1: Look at the example of init code in today's notes. When we do the CODECOPY operation, what are we overwriting?
A: We are copying the runtime bytecode to memory (at position 0).

Q2: Could the answer to Q1 allow an optimisation?
A: We could potentially remove the free memory pointer initialization code since it's not used.

Q3: Can you trigger a revert in the init code?
A: Sending any value (>0) in wei when deploying a new contract with a non-payable constructor will cause a revert.

Q4: Write some Yul to:
1. Add 0x07 to 0x08
2. Store the result at the next free memory location
3. Write this again in opcodes
A: Foundry Project

Q5: Can you think of a situation where the opcode EXTCODECOPY is used?
A: The EXTCODECOPY opcode can be used in the implementation of a proxy contract.

Q6: Complete the assembly exercises in this repo
A: Foundry Project

Lesson 2

Q1: Create a Solidity contract with one function. The solidity function should return the amount of ETH that was passed to it, and the function body should be written in assembly
A: Foundry Project

Q2: Do you know what this code is doing?
A: Deploys 2 contracts and then self destructs.

Q3: Explain what the following code is doing in the Yul ERC20 contract

function allowanceStorageOffset(account, spender) -> offset {
    offset := accountToStorageOffset(account)
    mstore(0, offset)
    mstore(0x20, spender)
    offset := keccak256(0, 0x40)
}

A: Calculates the storage location (offset) of the allowance between a specific address and a specific spender.

Lesson 3

Q1: The parameter X represents a function. Complete the function signature so that X is a standard ERC20 transfer function (other than the visibility). The query function should revert if the ERC20 function returns false

function query(uint _amount, address _receiver, X) public {
    ...
}

A:

function query(uint _amount, address _receiver, function (address, uint256) external returns (bool) transfer) public  {
        (bool result) = transfer(_receiver, _amount);
        if(!result) revert();
}

Q2: The following function checks function details passed in the data parameter.
function checkCall(bytes calldata data) external {}
The data parameter is bytes encoded representing the following
Function selector
Target address
Amount (uint256)

Complete the function body as follows: The function should revert if the function is not an ERC20 transfer function. Otherwise extract the address and amount from the data variable and emit an event with those details: event transferOccurred(address,uint256);

A:

contract W2_L3_Q2 {
    event transferOccurred(address target, uint256 value);
    
    function checkCall(bytes calldata data) external {
        (bytes4 functionSelector, address _t, uint256 _v) = abi.decode(data, (bytes4, address, uint256));
        bytes4 transferMethodId = 0xa9059cbb;
        assembly {
            if iszero(eq(functionSelector, transferMethodId)) { revert(0, 0) }
        }
        emit transferOccurred(_t, _v);
    }
}

Lesson 4

Q1: Clone this repo. Your task is to edit and optimise the Gas.sol contract. You cannot edit the tests. All the tests must pass. You can change the functionality of the contract as long as the tests pass. Try to get the gas usage as low as possible.
A: Foundry Project