FastLane Searchers submit their bids and solutions to the FastLane Protocol using EIP-712 signed messages. This method allows for off-chain data signing and on-chain verification, reducing gas costs and improving efficiency.
The submission to the PFL-Auction will be performed by Bundler EOA's. To establish a trusted a PFL-Auction transaction is constructed of 3 parts here:
UserOperation. : (opportunity transaction converted on PFL-Auction system)
SolverOperation : (generated and signed by searcher)
dAppOperation : (generated and signed by dAppSigner to hash userOperation and selected
solverOperations)
The above definitions are simplified to for more technical details we encourage to read our Atlas documentation
Submitting the Signed Message
This will be a two step process
Atlas will call the atlasSolverCall on the solver/searcher contracts
// Opionanted atlasSolverCall implementation which forwards// to a internal call using the solverOpDatafunctionatlasSolverCall(addresssolverOpFrom,addressexecutionEnvironment,addressbidToken,uint256bidAmount,bytescalldatasolverOpData,bytescalldata)externalpayablevirtualsafetyFirst(executionEnvironment,solverOpFrom)payBids(executionEnvironment,bidToken,bidAmount){(bool success,)=address(this).call{ value:msg.value }(solverOpData);if(!success)revertSolverCallUnsuccessful();}
1. Generate CallData for the Solver contract function
The first step is to generate and encode the backrun for a particular opportunity transaction
In our example the solve() function
Responsibilities:
perform backrun operation
makes sure the the contract has bidToken in bidAmount quantity (POL)
2. Generate SolverOperation to Submit for
The second part will be generating the a EIP-712 signed messages with a atlas specific format
EIP-712 like Message Structure
Searchers need to construct and sign a message containing the bid and operation details according to an Atlas format similar to the EIP-712 standard.
A SolverOperation contains the following important details
The message includes:
Bid Details: Bid token address, bid amount.
Operation Data: Encoded data for the solver operation.
dAppControl: PFL-Auction specific implementation of the Atlas hooks (pre-solver, post-solver)
dAppSigner: Account which will be signing the dAppControl operation
userOpHash: hash of User's Operation, for verification
deadline: is provided in block number not timestamp!
Description: This is the current address of the dAppControl contract, which is responsible for generating the userOpHash needed for the solver operation.
PFL-Auctions implementation for Atlas hooks (pre-solver, post-solver) and value distribution
// This function is called by atlasSolverCall() which forwards the solverOpData calldata
// by doing: address(this).call{value: msg.value}(solverOpData)
// where solverOpData contains the ABI-encoded call to solve()
function solve() public view onlySelf {
// SolverBase automatically handles paying the bid amount to the Execution Environment through
// the payBids modifier, as long as this contract has sufficient balance (ETH or WETH)
}
struct SolverOperation {
address from; // Solver address
address to; // Atlas address
uint256 value; // Amount of ETH(POL) required for the solver operation (used in `value` field of the solver call)
uint256 gas; // Gas limit for the solver operation
uint256 maxFeePerGas; // maxFeePerGas matching the opportunity tx
uint256 deadline; // block.number deadline for the solver operation
address solver; // Nested "to" address (used in `to` field of the solver call)
address control; // PFL Auction DAppControl (see documentation)
bytes32 userOpHash; // hash of User's Operation, for verification of user's tx (if not matched, solver wont be
// charged for gas)
address bidToken; // address(0) for ETH(POL)
uint256 bidAmount; // Amount of bidToken that the solver bids
bytes data; // Solver op calldata (used in `data` field of the solver call)
bytes signature; // Solver operation signature signed by SolverOperation.from
}