pcaversaccio

pcaversaccio

𝐖𝐨𝐫𝐤𝐢𝐧𝐠 𝐨𝐧 𝐰𝐡𝐚𝐭'𝐬 𝐧𝐞𝐱𝐭.

Member Since 4 years ago

@Daita-Technologies , Berne, Switzerland

Experience Points
13
follower
Lessons Completed
11
follow
Lessons Completed
193
stars
Best Reply Awards
33
repos

1751 contributions in the last year

Pinned
⚡ Hardhat plugin to deploy your smart contracts across multiple EVM chains with the same deterministic address.
⚡ Helper smart contract to make easier and safer usage of the `CREATE2` EVM opcode.
⚡ A smart contract to enable ERC-20 token meta-transactions on Ethereum.
⚡ Helper smart contract to make easier and safer usage of the `CREATE` EVM opcode.
⚡ A repository for Solidity-based smart contract games.
⚡ Similar to an ETH2 block explorer, but focused only on recent data.
Activity
Jan
22
1 day ago
Jan
21
2 days ago
Jan
20
3 days ago
Activity icon
issue

pcaversaccio issue Lossless-Cash/lossless-v3

pcaversaccio
pcaversaccio

Add `permit` method in LERC20

You should consider adding the permit method to LERC20, which can be used to change an account's ERC20 allowance by presenting a message signed by the account. By not relying on IERC20.approve, the token holder account doesn't need to send a transaction and thus is not required to hold Ether at all => enabling meta-transactions.

A gas-efficient implementation could look like this:

bytes32 public constant PERMIT_TYPEHASH =
    keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");

uint256 internal immutable INITIAL_CHAIN_ID;

bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;

mapping(address => uint256) public nonces;

function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");

        // Unchecked because the only math done is incrementing
        // the owner's nonce which cannot realistically overflow.
        unchecked {
            bytes32 digest = keccak256(
                abi.encodePacked(
                    "\x19\x01",
                    DOMAIN_SEPARATOR(),
                    keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))
                )
            );

            address recoveredAddress = ecrecover(digest, v, r, s);

            require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");

            allowance[recoveredAddress][spender] = value;
        }

        emit Approval(owner, spender, value);
    }

    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
        return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
    }

    function computeDomainSeparator() internal view virtual returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                    keccak256(bytes(name)),
                    keccak256("1"),
                    block.chainid,
                    address(this)
                )
            );
    }

The constructor would look like that:

    constructor(uint256 totalSupply_, string memory name_, string memory symbol_, address admin_, address recoveryAdmin_, uint256 timelockPeriod_, address lossless_) {
        _mint(_msgSender(), totalSupply_);
        _name = name_;
        _symbol = symbol_;
        admin = admin_;
        recoveryAdmin = recoveryAdmin_;
        timelockPeriod = timelockPeriod_;
        lossless = ILosslessController(lossless_);
        INITIAL_CHAIN_ID = block.chainid;
        INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
    }
Jan
19
4 days ago
started
started time in 3 days ago
started
started time in 3 days ago
Activity icon
issue

pcaversaccio issue comment Lossless-Cash/lossless-v3

pcaversaccio
pcaversaccio

Unchecked Solidity optimisations

In order to save gas you could implement the following unchecked array loops in your Solidity code:

Example setWhitelist:

// OLD VERSION
function setWhitelist(address[] calldata _addrList, bool value) public onlyLosslessAdmin {
    for(uint256 i; i < _addrList.length; i++) {
        whitelist[_addrList[i]] = value;
    }
}

// NEW VERSION
function setWhitelist(address[] calldata _addrList, bool value) public onlyLosslessAdmin {
    for(uint256 i; i < _addrList.length; ) {
        whitelist[_addrList[i]] = value;
        
        // An array can't have a total length
        // larger than the max uint256 value.
        unchecked {
            i++;
        }
    }
}
pcaversaccio
pcaversaccio

Another good way to save gas is regarding the _balances:

// OLD VERSION
function _mint(address account, uint256 amount) internal virtual {
    require(account != address(0), "LERC20: mint to the zero address");

    _totalSupply += amount;
    _balances[account] += amount;
    emit Transfer(address(0), account, amount);
}


// NEW VERSION
function _mint(address account, uint256 amount) internal virtual {
    require(account != address(0), "LERC20: mint to the zero address");
    
    _totalSupply += amount;
    
    // Cannot overflow because the sum of all user
    // balances can't exceed the max uint256 value.
    unchecked { 
        _balances[account] += amount;
    }
    emit Transfer(address(0), account, amount);
}
Activity icon
issue

pcaversaccio issue Lossless-Cash/lossless-v3

pcaversaccio
pcaversaccio

Unchecked array access

In order to save gas you could implement the following unchecked array loops in your Solidity code:

Example setWhitelist:

// OLD VERSION
function setWhitelist(address[] calldata _addrList, bool value) public onlyLosslessAdmin {
    for(uint256 i; i < _addrList.length; i++) {
        whitelist[_addrList[i]] = value;
    }
}

// NEW VERSION
function setWhitelist(address[] calldata _addrList, bool value) public onlyLosslessAdmin {
    for(uint256 i; i < _addrList.length; ) {
        whitelist[_addrList[i]] = value;
        
        // An array can't have a total length
        // larger than the max uint256 value.
        unchecked {
            i++;
        }
    }
}
started
started time in 3 days ago
started
started time in 3 days ago
Jan
18
5 days ago
started
started time in 4 days ago
started
started time in 4 days ago
Jan
17
6 days ago
started
started time in 5 days ago
started
started time in 5 days ago
started
started time in 5 days ago
Jan
16
1 week ago
Activity icon
published release xdeployer 1.1.1

pcaversaccio in pcaversaccio/xdeployer create published release xdeployer 1.1.1

createdAt 6 days ago
Activity icon
created tag
createdAt 6 days ago
push

pcaversaccio push pcaversaccio/xdeployer

pcaversaccio
pcaversaccio

renaming heco info & mixedCase naming convention networks

pcaversaccio
pcaversaccio

commit sha: fe30dce7206451c0fc80f64236d6353f1edc7528

push time in 6 days ago
push

pcaversaccio push pcaversaccio/create2deployer

pcaversaccio
pcaversaccio

renaming heco info & mixedCase naming convention networks

pcaversaccio
pcaversaccio

commit sha: f334cca5daaf6a8994b58fe2a54542079580597f

push time in 6 days ago
Jan
15
1 week ago
started
started time in 1 week ago
started
started time in 1 week ago
started
started time in 1 week ago
Previous