Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/KennieHarold/multi-metatx

Multi Meta Transaction on Ethereum with EIP-712 and ERC-2612 Standards
https://github.com/KennieHarold/multi-metatx

blockchain dapp eip-712 erc-2612 erc20 ethereum meta-transactions nodejs relayer smart-contracts solidity typescript

Last synced: about 1 month ago
JSON representation

Multi Meta Transaction on Ethereum with EIP-712 and ERC-2612 Standards

Awesome Lists containing this project

README

        

# ๐Ÿช™ [ERC20](https://eips.ethereum.org/EIPS/eip-20) Multi Meta Transaction

![banner](.github/assets/banner.png)

# โš™๏ธ Architecture

A meta transaction is a method that allows users to interact with the Ethereum network without requiring ETH for gas fees. In this setup, a user signs a transaction with their private key, while a third-party (a relayer) submits this transaction to the network and pays the gas fees. The transaction data is typically structured and signed according to the [EIP-712](https://eips.ethereum.org/EIPS/eip-712) standard, enhancing security and readability. Furthermore, the [ERC20 Permit](https://eips.ethereum.org/EIPS/eip-2612) method allows the token owner to delegate gas payments to another party, supporting the execution of the meta transaction. This process enhances the accessibility and usability of the Ethereum network, especially for users who do not hold ETH. To provide a better understanding, we've included a screenshot of the architecture.

![diagram](.github/assets/diagram.png)

## [EIP-712](https://eips.ethereum.org/EIPS/eip-712) - Typed Structured Data Hashing and Signing

EIP-712 is an Ethereum Improvement Proposal that provides a standard for structuring and displaying data in a human-readable format during Ethereum transactions. It improves the usability of signed data structures, making it easier for users to understand what
they're signing.

## [ERC-2612](https://eips.ethereum.org/EIPS/eip-2612) - Permit Extension for EIP-20 Signed Approvals

ERC-20 permit, also known as EIP-2612, is a method used in Ethereum blockchain that allows holders of ERC-20 tokens to approve the spending of their tokens via a signature, instead of requiring an Ethereum transaction.

## Forwarder Contract

The smart contract `Forwarder.sol` extends the EIP712 and entails the following core functions.

- `verify`: Verifies the signature based on the typed structured data.

```solidity
function verify(MetaTx calldata _tx, bytes calldata _signature) internal view returns (bool) {
address signer = _hashTypedDataV4(
keccak256(abi.encode(_TYPEHASH, _tx.from, _tx.to, _tx.token, _tx.amount, _tx.nonce))
).recover(_signature);

return signer == _tx.from && nonces[_tx.from] == _tx.nonce;
}
```

- `batchTransfer` Executes meta transactions in batches. If one transaction is invalid or has a malformed signature, the process continues as long as the remaining transactions are valid.

```solidity
function batchTransfer(MetaTxWithSig[] calldata _metaTxWithSig, uint256 gas) external onlyOwner {
uint256 transactionsLength = _metaTxWithSig.length;

for (uint256 i = 0; i < transactionsLength; ++i) {
bytes calldata signature = _metaTxWithSig[i].signature;
MetaTx calldata metaTx = _metaTxWithSig[i].metaTx;

if (verify(metaTx, signature) && whitelistedTokens[IERC20(metaTx.token)] && metaTx.to != address(0)) {
nonces[metaTx.from] = nonces[metaTx.from] + 1;
metaTx.token.transferFrom(metaTx.from, metaTx.to, metaTx.amount);
}

require(gasleft() > gas / 63, "Not enough gas");
}
}
```

## ERC20 Permit token

Here's the sample implementation of ERC20 Permit

```solidity
contract Token1 is ERC20, ERC20Permit {
constructor() ERC20("Token1", "T1") ERC20Permit("Token1") {
_mint(msg.sender, 1000000 * 10 ** 18);
}
}
```

# โšก๏ธ Demo
![demo](.github/assets//demo.gif)

# ๐Ÿ’ป Development
For this project to function, [Redis](https://redis.io/download/) must be installed, serving as our database to store transaction data.

After you clone the repository, change your directory to the project's directory and run the following commands:

#### 1. Copy the environment variables from `frontend` and `relayer` workspaces

```bash
cp frontend/.env.development frontend/.env
cp relayer/.env.development relayer/.env
```

#### 2. Install npm modules

```bash
yarn install
```

#### 3. Start the Redis server. In your terminal simply run:

```bash
redis-server
```

#### 4. Start [Hardhat](https://hardhat.org/) local node server. Open a new tab in your terminal, change directory to the `contracts` folder and simply run:

```bash
npx hardhat node
```

#### 5. Deploy the smart contracts. Open a new tab in your terminal, simply run:

```bash
yarn contracts:deploy:localhost
```

It should display something like this in your terminal.

```bash
Forwarder deployed to: 0x...123
Token1 whitelisted and deployed to 0x...123
Token2 whitelisted and deployed to 0x...123
Token3 whitelisted and deployed to 0x...123
```

#### 6. Setup the environment variables

In the relayer workspace, copy and paste the deployed `forwarder` contract address, along with the private key of Hardhat's deployer, typically designated as account index 0.

```bash
FORWARDER_LOCALHOST_ADDRESS=
PRIV_KEY=
```

In the `frontend` workspace, copy and paste as well the `forwarder` contract address.

```bash
NEXT_PUBLIC_FORWARDER_LOCALHOST_ADDRESS
```

Same in the `frontend` workspace, copy and paste the tokens addresses in the `blockchain.ts` file under the `utils` folder.

```javascript
token: {
tokens: [
{
address: {
localhost: '0x...',
sepolia: '',
goerli: ''
}
},
{
address: {
localhost: '0x..',
sepolia: '',
goerli: ''
}
},
{
address: {
localhost: '0x..',
sepolia: '',
goerli: ''
}
}
],
}
```

#### 7. Open a new tab in your terminal and run the `relayer` server

```bash
yarn relayer:dev
```

#### 8. Open a new tab in your terminal and run the `frontend`

```bash
yarn frontend:dev
```

#### 9. In your browser, navigate to `localhost:3000`, and that's it you successfully run the project. Have fun! ๐Ÿ˜„

# ๐Ÿงช Unit Tests

We utilize [Hardhat](https://hardhat.org/) given its robust capabilities for testing smart contracts, encompassing Solidity debugging and clear error messages.

To run the test suite. Simply run:

```bash
yarn contracts:test
```

Here's the sample report from the contract's test suite

```
ยท--------------------------------|----------------------------|-------------|-----------------------------ยท
| Solc version: 0.8.17 ยท Optimizer enabled: false ยท Runs: 200 ยท Block limit: 30000000 gas โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| Methods โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| Contract ยท Method ยท Min ยท Max ยท Avg ยท # calls ยท usd (avg) โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| Forwarder ยท batchTransfer ยท - ยท - ยท 547434 ยท 1 ยท - โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| Forwarder ยท whitelistToken ยท - ยท - ยท 46764 ยท 3 ยท - โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| Token1 ยท permit ยท 77091 ยท 77103 ยท 77099 ยท 3 ยท - โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| Token1 ยท transfer ยท 52143 ยท 52155 ยท 52151 ยท 3 ยท - โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| Token2 ยท permit ยท 77067 ยท 77103 ยท 77087 ยท 3 ยท - โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| Token2 ยท transfer ยท 52143 ยท 52155 ยท 52151 ยท 3 ยท - โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| Token3 ยท permit ยท 77091 ยท 77103 ยท 77095 ยท 3 ยท - โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| Token3 ยท transfer ยท 52143 ยท 52155 ยท 52151 ยท 3 ยท - โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| Deployments ยท ยท % of limit ยท โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| Forwarder ยท - ยท - ยท 1924066 ยท 6.4 % ยท - โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| Token1 ยท - ยท - ยท 2269191 ยท 7.6 % ยท - โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| Token2 ยท - ยท - ยท 2269191 ยท 7.6 % ยท - โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
| Token3 ยท - ยท - ยท 2269191 ยท 7.6 % ยท - โ”‚
ยท--------------------------------|--------------|-------------|-------------|---------------|-------------ยท
```

# ๐Ÿ“œ License

This project is licensed under [GNU General Public License v3](https://opensource.org/license/gpl-3-0/).

# ๐Ÿ’œ Thank you!

If this project interests you, follow me on Twitter

[![Kennie Harold](https://img.shields.io/badge/twitter-08A0E9?style=for-the-badge&logo=twitter&logoColor=white)](https://twitter.com/eikenn99)