shardeum / bug-reporting

59 stars 35 forks source link

Solidity ```create2``` contract is deployed with contract address data empty ```extcodesize(account) == 0``` #12

Closed MarcusWentz closed 1 year ago

MarcusWentz commented 1 year ago
What is the issue?

Deploying with create2 has incorrect data inside the new smart contract on Shardeum Liberty 2.1.

What impact does the issue have?

Contracts cannot be deployed with create2 with this issue since the data is not correct.

-Deployed contract has:

-extcodesize(account) == 0 in Yul (Assembly in Solidity) 
-Shardeum Explorer shows contract code as 0xdde84026de842c6171238b977ee805f06625459e48a0a53e1d12b04ca2eb7de3
How to do reproduce the issue?

Deployed Create2Factory and ContractToDeploy (from create2) from Remix IDE:

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

error notOwner();

contract ContractToDeploy {

    uint public storageSlot0;
    address public immutable Owner;

    constructor(address inputAddress) payable {
        Owner = inputAddress; //Need to put address as input instead of msg.sender because msg.sender will be another contract with CREATE2 salt deploy.
    }

    function changeValue(uint updateStorageSlot) public {
        storageSlot0 = updateStorageSlot;
    }

    function killThisContract() public { //After a contract is killed at an address, you can deploy another contract at that address.
        if(msg.sender != Owner) { revert notOwner(); }
        selfdestruct(payable(Owner)); //Deletes all data from this contract.
    }

}

contract Create2Factory { //Modified from: "Create2 | Solidity 0.8" by  Smart Contract Programmer https://www.youtube.com/watch?v=883-koWrsO4&ab_channel=SmartContractProgrammer

    event create2Event(address deployedAddressEvent);

    function create2DeployContract(bytes32 _salt, address ownerAddress) public payable {                              // Salt example:  0x0000000000000000000000000000000000000000000000000000000000000000
        ContractToDeploy deployedAddress = new ContractToDeploy {value: msg.value, salt: _salt}(ownerAddress); // Another salt example: 0x123456789abcdef0000000000000000000000000000000000000000000000000
        emit create2Event(address(deployedAddress));
    }

    function precomputeAddress(uint _salt, address ownerAddress) public view returns (address) {
        bytes memory creationCodeValue = abi.encodePacked(type(ContractToDeploy).creationCode, abi.encode(ownerAddress));
        bytes32 hash = keccak256(abi.encodePacked(bytes1(0xff), address(this), _salt, keccak256(creationCodeValue)));
        return address(uint160(uint(hash)));
    }

}

contract checkIfContractIsDeployed {

    function isContractTest(address _addr) public view returns (bool isContract){
        uint32 size;
        assembly {
            size := extcodesize(_addr)
        }
        return (size > 0);
    }
}
What other resources can you share regarding this issue?

Liberty 2.1 contract addresses:

Create2Factory:

https://explorer-liberty20.shardeum.org/account/0x7bbb7716b346874e31fa40f1c959868720f25fd2

ContractToDeploy:

https://explorer-liberty20.shardeum.org/account/0x0eb5bcb4fd0d6aa8789550c5892dd119dedf2216

checkIfContractIsDeployed:

https://explorer-liberty20.shardeum.org/account/0x204d7e79c1b8bed6b2a533377be5b4780ded6ce2

MarcusWentz commented 1 year ago

Related to issue:

https://github.com/Shardeum/shardeum-bug-reporting/issues/11

This issue should be considered high priority, since Uniswap V2 function createPair depends on create2 for new liquidity pairs:

https://github.com/Uniswap/v2-core/blob/master/contracts/UniswapV2Factory.sol#L31

function createPair(address tokenA, address tokenB) external returns (address pair) {
    require(tokenA != tokenB, 'UniswapV2: IDENTICAL_ADDRESSES');
    (address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
    require(token0 != address(0), 'UniswapV2: ZERO_ADDRESS');
    require(getPair[token0][token1] == address(0), 'UniswapV2: PAIR_EXISTS'); // single check is sufficient
    bytes memory bytecode = type(UniswapV2Pair).creationCode;
    bytes32 salt = keccak256(abi.encodePacked(token0, token1));
    assembly {
        pair := create2(0, add(bytecode, 32), mload(bytecode), salt)
    }
    IUniswapV2Pair(pair).initialize(token0, token1);
    getPair[token0][token1] = pair;
    getPair[token1][token0] = pair; // populate mapping in the reverse direction
    allPairs.push(pair);
    emit PairCreated(token0, token1, pair, allPairs.length);
}
MarcusWentz commented 1 year ago

I tested a bug patch on a local node.

The create2 issue looks fixed, since the contract data size updates and storage data is added now.

Closing issue now since this bug patch will be added soon.

However,

function killThisContract() public { //After a contract is killed at an address, you can deploy another contract at that address.
    if(msg.sender != Owner) { revert notOwner(); }
    selfdestruct(payable(Owner)); //Deletes all data from this contract.
}

does not delete the contract data with storage slots, so issue:

https://github.com/Shardeum/shardeum-bug-reporting/issues/15

is still present.

szefo8181 commented 7 months ago

How does the team verify the validator's activity on the blockchain?

I understand that individual rewards may not be significant, but what concerns me is the lack of traceability on the blockchain regarding who was active and earned rewards. I'm unsure how this is verified by the team.

Although my node was active on the blockchain, there is no trace of it on the blockchain itself. I'm unsure how the team will verify validators at this point and determine their activity levels.

Currently, the information available on the blockchain only indicates how many SHM tokens were staked on each validator, including the Metamask address of the person who staked their tokens.

In my case, the problem arises from the fact that since November 2022, I've had a validator set up, but rewards have been recorded on the blockchain only once. Despite being active numerous times for extended periods, rewards have never been deposited into my Metamask address. The only instance when there was a trace on the blockchain and SHM tokens were deposited into my Metamask address occurred when:

Feedback for the team: I would like to report a problem regarding the lack of traceability on the blockchain regarding the validator's activity and associated rewards. I'm uncertain about the steps the team will take to verify the activity of validators and resolve this issue. Please provide clarification on this matter and assistance in resolving the problem. Thank you.