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)