Supporting gasless transactions with Relayers and Paymasters in Allo2. ERC4337 Account Abstraction works out of the box without any changes needed. ### What are Relayers, Paymasters, and ERC2771? - When a contract is called we normally use `msg.sender` to know who is calling the function (same with `msg.value` but lets focus on sender) - However, if we want to enable gasless transaction we would use a Relayer or Paymaster - A Relayer or Paymaster is a wallet or a contract that forwards our transaction to the smart contract we want to call. - It can be a Node.js API using a simple ethers Wallet or the OpenZeppelin Relay SDK, or it can be a service such as Gelato or OpenGSN that uses a wrapping RPC provider to relay our transaction. - Now, in order for the contract we call to use our address instead of the relayers, we need to implement a trusted forwarder (ERC2771) in our contract - ERC2771 is an abstract contract that lets us implement a `_msgSender` function - This function checks if the caller is our trusted forwarder (our relayer) and if so it gives us the original sender of the transaction - Paymasters can be coded to accept payments in ERC20, ERC721 or any other logic of choice before calling the contract ### Potential use-cases - Sign in with Web2 (email or social) and vote directly, essentially hides the web3 - With Privy, wallets can be pre-generated to an email address and later claimed by the owner of the email account. These wallets can be funded with tokens that are used as payments or gating - Stripe Checkout could be added and in the checkout success event mint tokens of choice to the wallet ### What changes are required to support it? - All the places that use `msg.sender` or `msg.value` - Implement ERC2771 for these contracts with a configured trusted forwarder address (the relayer/paymaster) - This happens in mainly two categories: - Pool management (create, fund) - Strategy calls (registerRecipient, allocate, distribute) - This means, to support gasless transactions for Pool management, we need to update Allo.sol with ERC2771 and deploy an Allo owned Relayer/Paymaster contract - Strategy contracts can choose if to support and implement their own ERC2771 ```solidity // Current implementation function _allocate(uint256 _poolId, bytes memory _data) internal { pools[_poolId].strategy.allocate{value: msg.value}(_data, msg.sender); } // Proposed implementation to support ERC2771 function _allocate(uint256 _poolId, bytes memory _data) internal { IStrategy strategy = pools[_poolId].strategy; // Is it possible to call the strategy contracts for the sender and value? address sender = strategy._msgSender(); uint256 value = strategy._msgValue(); strategy.allocate{value: value}(_data, sender); } ``` ### Resources **Wallets** - Privy (https://www.privy.io) - Web3Auth (https://web3auth.io) - MagicLink (https://magic.link) **Relay services** - OpenZeppelin Relay (https://docs.openzeppelin.com/defender/relay) - Gelato (https://www.gelato.network/relay) - OpenGSN (https://opengsn.org) **ERC2771** - EIP (https://eips.ethereum.org/EIPS/eip-2771) - OpenZeppelin ERC2771Context (https://docs.openzeppelin.com/contracts/4.x/api/metatx)