Bundle Requirements
Transaction Requirements for Solver Operations
Gas Parameters for
userOpHash
GenerationLegacy Transactions:
gasPrice
: Must match the opportunity-creating transaction.
Type 2 (EIP-1559) Transactions:
maxFeePerGas
andmaxPriorityFeePerGas
: Must match the opportunity-creating transaction.
Implementation:
Ensure meta transactions (EIP-712) use gas parameters identical to the opportunity-creating transaction to accurately generate
userOpHash
.
userOpHash
GenerationPurpose: Identifies the opportunity transaction in the PFL-Auction context
Procedure:
Call the
PFL-Auction
dAppControl
contract with the matched gas parameters.The transaction type influences the gas parameters used but does not need separate handling.
Solver Operation Handling
Behavior:
Does not differentiate between legacy and Type 2 transactions.
Relies solely on the correctly generated
userOpHash
for processing.
Implications:
No adjustments needed within the solver for different transaction types.
Please follow Bundle Format guide for more detailed guide for Solver Operation
Note: In Atlas, the transaction hash alone is not sufficient. Instead, we incorporate additional Atlas-specific parameters and configuration details, combining them with the original transaction hash to create a new, unique identifier. This rehashing process ensures that each transaction reflects Atlas-specific context and configurations accurately.
The Example below show how to obtain the correct userOpHash
to be passed as reference ot the targeted opportunity transaction.
import { Contract, Interface, JsonRpcProvider, keccak256, parseEther, TypedDataDomain, Wallet } from "ethers";
const provider = new JsonRpcProvider("https://polygon.llamarpc.com");
const dappControlAddr = "0x3e23e4282FcE0cF42DCd0E9bdf39056434E65C1F"; // current dappControl address (review docs)
const PFLControlAbi = [
{
"inputs": [
{ "internalType": "bytes32", "name": "oppTxHash", "type": "bytes32" },
{ "internalType": "uint256", "name": "oppTxMaxFeePerGas", "type": "uint256" },
{ "internalType": "uint256", "name": "oppTxMaxPriorityFeePerGas", "type": "uint256" },
{ "internalType": "address", "name": "fastLaneSigner", "type": "address" }
],
"name": "getBackrunUserOpHash",
"outputs": [{ "internalType": "bytes32", "name": "userOpHash", "type": "bytes32" }],
"stateMutability": "view",
"type": "function"
},
];
const dappControl = new Contract(dappControlAddr, PFLControlAbi, provider);
async function main() {
const feeData = await provider.getFeeData();
const opportunityRawTx = "0x000"; //binary string of opportunity tx
const isLegacyTx = isLegacy(opportunityRawTx);
//match opportunity tx transaction type
const maxFeePerGas = isLegacyTx ? feeData.gasPrice: feeData.maxFeePerGas;
const maxPriorityFeePerGas = isLegacyTx ? feeData.gasPrice : feeData.maxPriorityFeePerGas,
// Get the userOpHash for the opportunity tx calling the PFL dappControl contract
//NOTE: we need to use the same transaction type as the opportunity tx
const userOpHash = await dappControl.getBackrunUserOpHash(
keccak256(opportunityRawTx),
maxFeePerGas,
maxPriorityFeePerGas,
dAppOpSignerAddr
);
// additional code for generation of the solver operation and bidSubmission
}
main().catch(console.error);
Last updated