Skip to main content

SolverBase

The SolverBase contract serves as a foundational component for Solvers within the Atlas Protocol. It ensures the safe execution of solver operations, handles escrow reconciliation, and manages bid payments. This contract is designed to work seamlessly with DAppControl contracts that have the invertBidValue flag set to false. For DAppControl contracts with invertBidValue set to true, use the SolverBaseInvertBid contract instead.

Inheritance

State Variables

VariableTypeVisibilityDescription
WETH_ADDRESSaddresspublicImmutable address of the Wrapped ETH (WETH) contract.
_owneraddressinternalImmutable address of the contract owner.
_atlasaddressinternalImmutable address of the deployed Atlas protocol.

Errors

Error NameDescription
SolverCallUnsuccessfulThrown when the solver operation execution fails.
InvalidEntryThrown when an unauthorized entry point is detected.
InvalidCallerThrown when the caller is not the designated owner.

Constructor

constructor(address weth, address atlas, address owner)

Description

Initializes the SolverBase contract by setting the WETH address, Atlas protocol address, and the contract owner.

Parameters

NameTypeDescription
wethaddressAddress of the Wrapped ETH (WETH) contract.
atlasaddressAddress of the deployed Atlas protocol.
owneraddressAddress of the contract owner.

External Functions

atlasSolverCall

function atlasSolverCall(
address solverOpFrom,
address executionEnvironment,
address bidToken,
uint256 bidAmount,
bytes calldata solverOpData,
bytes calldata
)
external
payable
virtual
safetyFirst(executionEnvironment, solverOpFrom)
payBids(executionEnvironment, bidToken, bidAmount)
{
(bool success,) = address(this).call{ value: msg.value }(solverOpData);
if (!success) revert SolverCallUnsuccessful();
}

Description

Executes a solver operation within the Atlas Protocol. This function performs safety checks, executes the solver operation, and handles bid payments.

Parameters

NameTypeDescription
solverOpFromaddressAddress initiating the solver operation.
executionEnvironmentaddressAddress of the execution environment for the solver operation.
bidTokenaddressAddress of the token used for bidding. Use address(0) for ETH.
bidAmountuint256Amount of the bid in the specified bidToken.
solverOpDatabytes calldataEncoded data for the solver operation execution.
_unusedbytes calldataReserved for future use (currently unused).

Return Values

This function does not return any values directly but may emit events or revert on failure.

Requirements

  • The caller must be the Atlas protocol contract.
  • The solverOpFrom must be the designated owner.
  • The contract must have enough Ether to process the simulation.

Behavior

  1. Safety Checks: Ensures that the caller is authorized and that the operation originates from the correct owner.
  2. Solver Operation Execution: Executes the solver operation using a low-level call.
  3. Bid Payment: After execution, pays the bid to the specified execution environment, either in ETH or ERC20 tokens.

Reverts

  • SolverCallUnsuccessful if the solver operation execution fails.
  • InvalidEntry if the caller is not the Atlas protocol.
  • InvalidCaller if the solverOpFrom is not the designated owner.

Modifiers

safetyFirst

modifier safetyFirst(address executionEnvironment, address solverOpFrom)

Description

Performs safety checks before and after the execution of a solver operation.

Parameters

NameTypeDescription
executionEnvironmentaddressAddress of the execution environment.
solverOpFromaddressAddress initiating the solver operation.

Behavior

  1. Pre-Execution Checks:

    • Verifies that the caller is the Atlas protocol contract.
    • Ensures that the operation originates from the designated owner.
  2. Post-Execution Reconciliation:

    • Calculates any shortfall between the sent Ether (msg.value) and the protocol's shortfall requirement.
    • Withdraws the necessary Ether from WETH if the contract's balance is insufficient.
    • Calls the reconcile function on the Atlas protocol to handle the shortfall.

Reverts

  • InvalidEntry if the caller is not the Atlas protocol.
  • InvalidCaller if the solverOpFrom is not the designated owner.

payBids

modifier payBids(address executionEnvironment, address bidToken, uint256 bidAmount)

Description

Handles the payment of bids after the execution of a solver operation.

Parameters

NameTypeDescription
executionEnvironmentaddressAddress to receive the bid payment.
bidTokenaddressAddress of the token used for bidding. Use address(0) for ETH.
bidAmountuint256Amount of the bid to be paid.

Behavior

  1. Post-Execution Bid Payment:
    • If bidToken is address(0), pays the bid amount in ETH.
      • Withdraws the required Ether from WETH if the contract's balance is insufficient.
      • Transfers Ether to the executionEnvironment.
    • If bidToken is an ERC20 token, transfers the bid amount to the executionEnvironment using SafeTransferLib.

Reverts

  • Reverts if the contract does not have enough Ether or ERC20 tokens to cover the bid amount.

Internal Functions

_transferETH

function _transferETH(address to, uint256 amount) internal

Description

Transfers a specified amount of Ether to a given address.

Parameters

NameTypeDescription
toaddressRecipient address.
amountuint256Amount of Ether to transfer.

Behavior

  • Uses SafeTransferLib to safely transfer Ether to the specified address.

Reverts

  • Reverts if the Ether transfer fails.

_transferERC20

function _transferERC20(address token, address to, uint256 amount) internal

Description

Transfers a specified amount of ERC20 tokens to a given address.

Parameters

NameTypeDescription
tokenaddressERC20 token contract address.
toaddressRecipient address.
amountuint256Amount of tokens to transfer.

Behavior

  • Uses SafeTransferLib to safely transfer ERC20 tokens to the specified address.

Reverts

  • Reverts if the token transfer fails.

Error Handling

The SolverBase contract utilizes custom errors to handle various failure scenarios efficiently:

Error NameDescription
SolverCallUnsuccessfulThrown when the solver operation execution fails.
InvalidEntryThrown when an unauthorized entry point is detected.
InvalidCallerThrown when the caller is not the designated owner.

Usage Examples

Deploying the SolverBase Contract

// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.25;

import { SolverBase } from "./SolverBase.sol";

contract MySolver is SolverBase {
constructor(address weth, address atlas, address owner)
SolverBase(weth, atlas, owner)
{
// Additional initialization if necessary
}

// Implement additional solver-specific logic if needed
}

Executing a Solver Operation

// Assume `solver` is an instance of SolverBase deployed at address `solverAddress`
// and `atlas` is the deployed Atlas protocol contract.

UserOperation memory userOp = UserOperation({
// Initialize user operation parameters
});

SolverOperation memory solverOp = SolverOperation({
// Initialize solver operation parameters
});

DAppOperation memory dAppOp = DAppOperation({
// Initialize DApp operation parameters
});

// Execute the solver call
(bool success, Result memory simResult, uint256 errorCode) = solver.atlasSolverCall{ value: msg.value }(
userOp.from,
executionEnvironment,
bidToken,
bidAmount,
abi.encodeWithSignature("executeSolver(bytes)", solverOpData),
""
);

// Handle the result
require(success, "Solver operation failed");

Security Considerations

  • Access Control:
    Ensure that only authorized entities (e.g., the Atlas protocol contract) can invoke the atlasSolverCall function. The safetyFirst modifier enforces this by checking the caller and the originator of the solver operation.

  • Reentrancy Protection:
    The contract uses low-level call to execute solver operations. Ensure that the called functions are not vulnerable to reentrancy attacks. Consider using the Checks-Effects-Interactions pattern or Reentrancy Guards if extending functionality.

  • Handling ETH and ERC20 Transfers:
    Utilize SafeTransferLib to handle token transfers securely, preventing common pitfalls like missing return values or failing transfers.

  • Error Handling:
    Implement comprehensive error handling to revert transactions in case of failures, ensuring that the contract's state remains consistent.

Best Practices

  1. Thorough Testing:
    Rigorously test all solver operations to handle expected and edge-case scenarios, ensuring the contract behaves as intended under various conditions.

  2. Security Audits:
    Conduct comprehensive security audits to identify and mitigate potential vulnerabilities, especially since the contract handles funds and critical operations.

  3. Clear Documentation:
    Maintain detailed documentation for each function and modifier, explaining their purpose and usage to facilitate future maintenance and onboarding.

  4. Upgradeability Considerations:
    If the contract is intended to be upgradeable, implement proper upgrade mechanisms and storage patterns to prevent storage collisions and ensure seamless upgrades.

  5. Event Emission:
    Although the SolverBase contract does not emit custom events, consider emitting events in extended contracts to facilitate easier tracking and monitoring of solver operations.

Conclusion

The SolverBase contract provides a robust and secure foundation for implementing solver operations within the Atlas Protocol. By ensuring safety checks, managing bid payments, and handling escrow reconciliation, it enables seamless integration of solver functionalities with decentralized applications. Adhering to best practices and thorough testing will further enhance the contract's reliability and security within the ecosystem.