Metaplay
Metaplay© is a different way of betting besides regular play. Players can enable Metaplay in their settings. Metaplay© is technically speaking meta transactions combined with session keys. Session keys remove wallet pop ups, a most requested feature. This leads to confirmationless bets. Meta transactions achieve gas abstraction, so users can pay fees with the ERC-20 bet token they are wagering with.
Below follows an explanation of the technical flow and architecture of Metaplay©.
Technical flow
Session wallet: frontend and trusted forwarder
When a player wants to use Metaplay©, a session wallet is required. The frontend checks if a session private key is stored on localStorage
. If a key exists, the frontend uses that key to access the session wallet. This session wallet is allowed to sign requests on behalf of the wallet that generated the session wallet (transaction signer).
If a key does not exist yet, the frontend calls an ether.js function to generate a new, random session wallet with a session private key. Ethers guarantees that the key is generated randomly. That key is then stored in the user’s browser in localStorage
. This allows the user to keep using Metaplay© across sessions and tabs.
The user can delete the key from the browser's localStorage
at any given moment:
Next, the session wallet is set up on-chain on the Trusted Forwarder contract by calling the setSigner
function (involves confirming a transaction). The session wallet address is enabled and saved in the Forwarder contract, the game contracts (‘targets’) are batch approved and an expiry time for the session wallet is set (one month). After one month the user needs to re-approve the Forwarder contract. During this month the user can revoke the allowances on the Forwarder contract for the session wallet at any time.
The session wallet can be used for meta transactions based on ERC-2771. This achieves gas abstraction which means that native tokens are no longer required during betting. Fees are paid in ERC-20 bet tokens, such as USDC. Tokens with reliable pricefeeds are eligible to become Metaplay© bet tokens. The user needs to approve the bet tokens on the Forwarder contract (involves confirming a transaction). Note that Metaplay© is unavailable for native tokens (ETH, FTM, MATIC).
Whenever a user clicks ‘Play’, the frontend code accesses the session private key from the user. The frontend code uses the key of the session wallet which is authorised to sign EIP-712 signature requests on behalf of the user’s wallet. In short, the frontend handles the signing for the user, removing the need for any pop ups from the wallet. The off-chain request is then sent to the backend server.
Malicious intent restricted
If a malicious party would ever obtain the session private key, their actions are extremely limited. They are unable to steal funds from the wallet, rendering an attack mostly useless since there is no financial gain available.
The key can only be used to interact with the game contracts.
It is not possible to transfer tokens out of the wallet.
Placing wagers can only happen with ERC-20 bet tokens approved on the Forwarder contract.
The total amount that can be wagered (volume) is limited to the amount the user has approved on the Forwarder contract.
Note: Metamask sets
Max
to the user's balance and users get warned when approving infinite, leading to increased security.
Betting against ~1% house edge does not lead to direct loss of funds; on the contrary, it can lead to profits.
Losses do not end up in malicious hands, they fall into the bankroll.
Native tokens are unavailable on Metaplay© and thus can never be accessed.
In summary: with the key it is only possible to use approved ERC-20 bet tokens and place wagers against ~1% house edge limited to a total volume of the amount approved. A malicious party is unable to get their hands on any funds, meaning there is no incentive to steal the key.
Backend (gas relayer)
The backend server receives the user’s request. The backend verifies that the transaction does not fail if it gets executed and sends the transaction on-chain.
Trusted forwarder (contract)
On-chain, the signature and nonce are checked to make sure that the user signed the request to keep the user's wallet safe.The forwarder then sends the request forward, communicating with the recipient/target contracts (game contracts).
Game contracts (recipient)
The casino contracts underwent minimal changes. The most important change was finding out who is sending the transaction, because the Forwarder contract executes transactions on behalf of the user. This is done with the function function _msgSender()
, which can be found on the Common.sol and game contracts.
Forwarder extra
The forwarder contract keeps track of the user's "set and signed (immutable) gasLimit
and Value
sent" to convert those values to the ERC-20 fee token chosen by the user and collected from the user. This is also the reason an approval is needed for the fee token. The operator pays transaction fees and VRF fees, so fees need to be collected from the user to cover the cost from the operator.
Architecture overview
Future improvements
Lowering gas costs by batching requests when there is a high number of requests;
Especially on Arbitrum, by modifying the calldata so it uses less space on L1 and is therefor cheaper.
Decentralising the operator (gas relayers);
Subsidising bet fees;
Gas fees: gasless transactions
VRF fees
Allow approving without native token;
Removing approvals for fee token through subsidising those fees;
Batch pay upfront for transactions.
Last updated