SolverBaseInvertBid
The SolverBaseInvertBid
contract serves as a foundational component for Solvers within the Atlas Protocol, specifically designed to work with DAppControl
contracts that have the invertBidValue
flag set to true
. It ensures the safe execution of solver operations, handles escrow reconciliation, manages bid payments, and optionally retrieves bids based on the configuration.
Inheritance
- Interfaces:
ISolverContract
- Libraries:
SafeTransferLib
from SoladyIERC20
from OpenZeppelin
State Variables
Variable | Type | Visibility | Description |
---|---|---|---|
WETH_ADDRESS | address | public | Immutable address of the Wrapped ETH (WETH) contract. |
_owner | address | internal | Immutable address of the contract owner. |
_atlas | address | internal | Immutable address of the deployed Atlas protocol. |
_bidRetrievalRequired | bool | internal | Indicates if bid retrieval from the Execution Environment is required. |
Errors
Error Name | Description |
---|---|
SolverCallUnsuccessful | Thrown when the solver operation execution fails. |
InvalidEntry | Thrown when an unauthorized entry point is detected. |
InvalidCaller | Thrown when the caller is not the designated owner. |
Constructor
constructor(address weth, address atlas, address owner, bool bidRetrievalRequired)
Description
Initializes the SolverBaseInvertBid
contract by setting the WETH address, Atlas protocol address, contract owner, and configuring bid retrieval requirements.
Parameters
Name | Type | Description |
---|---|---|
weth | address | Address of the Wrapped ETH (WETH) contract. |
atlas | address | Address of the deployed Atlas protocol. |
owner | address | Address of the contract owner. |
bidRetrievalRequired | bool | Determines if bid retrieval from the Execution Environment is necessary. |
External Functions
atlasSolverCall
function atlasSolverCall(
address solverOpFrom,
address executionEnvironment,
address bidToken,
uint256 bidAmount,
bytes calldata solverOpData,
bytes calldata /* extraReturnData */
)
external
payable
virtual
safetyFirst(executionEnvironment, solverOpFrom)
receiveBids(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, optionally retrieves bids based on configuration, executes the solver operation, and handles bid payments.
Parameters
Name | Type | Description |
---|---|---|
solverOpFrom | address | Address initiating the solver operation. |
executionEnvironment | address | Address of the execution environment for the solver operation. |
bidToken | address | Address of the token used for bidding. Use address(0) for ETH. |
bidAmount | uint256 | Amount of the bid in the specified bidToken . |
solverOpData | bytes calldata | Encoded data for the solver operation execution. |
_unused | bytes calldata | Reserved 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.
- If
_bidRetrievalRequired
istrue
, thebidToken
must not beaddress(0)
.
Behavior
- Safety Checks: Ensures that the caller is authorized and that the operation originates from the correct owner.
- Bid Retrieval (Optional): If bid retrieval is required, retrieves the bid from the Execution Environment.
- Solver Operation Execution: Executes the solver operation using a low-level
call
. - 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 thesolverOpFrom
is not the designated owner.Solver cannot retrieve ETH from EE
if bid retrieval is required butbidToken
isaddress(0)
.
Modifiers
safetyFirst
modifier safetyFirst(address executionEnvironment, address solverOpFrom)
Description
Performs safety checks before and after the execution of a solver operation.
Parameters
Name | Type | Description |
---|---|---|
executionEnvironment | address | Address of the execution environment. |
solverOpFrom | address | Address initiating the solver operation. |
Behavior
- Pre-Execution Checks:
- Verifies that the caller is the Atlas protocol contract.
- Ensures that the operation originates from the designated owner.
- 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.
- Calculates any shortfall between the sent Ether (
Reverts
InvalidEntry
if the caller is not the Atlas protocol.InvalidCaller
if thesolverOpFrom
is not the designated owner.
receiveBids
modifier receiveBids(address executionEnvironment, address bidToken, uint256 bidAmount)
Description
Handles the retrieval of bids before the execution of a solver operation based on the contract's configuration.
Parameters
Name | Type | Description |
---|---|---|
executionEnvironment | address | Address to receive the bid payment. |
bidToken | address | Address of the token used for bidding. Use address(0) for ETH. |
bidAmount | uint256 | Amount of the bid to be retrieved and paid. |
Behavior
- Bid Retrieval (Conditional):
- If
_bidRetrievalRequired
istrue
, ensures that thebidToken
is notaddress(0)
. - Uses
SafeTransferLib
to safely transfer the bid amount from the Execution Environment to the Solver contract.
- If
- Post-Retrieval Actions:
- Proceeds with the execution of the solver operation.
Reverts
Solver cannot retrieve ETH from EE
if bid retrieval is required butbidToken
isaddress(0)
.
Internal Functions
_transferETH
function _transferETH(address to, uint256 amount) internal
Description
Transfers a specified amount of Ether to a given address.
Parameters
Name | Type | Description |
---|---|---|
to | address | Recipient address. |
amount | uint256 | Amount 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
Name | Type | Description |
---|---|---|
token | address | ERC20 token contract address. |
to | address | Recipient address. |
amount | uint256 | Amount 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 SolverBaseInvertBid
contract utilizes custom errors to handle various failure scenarios efficiently:
Error Name | Description |
---|---|
SolverCallUnsuccessful | Thrown when the solver operation execution fails. |
InvalidEntry | Thrown when an unauthorized entry point is detected. |
InvalidCaller | Thrown when the caller is not the designated owner. |
Usage Examples
Deploying the SolverBaseInvertBid Contract
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.25;
import { SolverBaseInvertBid } from "./SolverBaseInvertBid.sol";
contract MySolverInvertBid is SolverBaseInvertBid {
constructor(address weth, address atlas, address owner, bool bidRetrievalRequired)
SolverBaseInvertBid(weth, atlas, owner, bidRetrievalRequired)
{
// Additional initialization if necessary
}
// Implement additional solver-specific logic if needed
}
```
### Executing a Solver Operation with Bid Retrieval
```solidity
// Assume `solver` is an instance of SolverBaseInvertBid 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
});
address executionEnvironment = 0xExecutionEnvironmentAddress;
address bidToken = 0xBidTokenAddress; // ERC20 token address
uint256 bidAmount = 1000 * 10**18; // Example bid amount
// Execute the solver call with bid retrieval
(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.
- **Bid Retrieval Validation:**
When bid retrieval is required, ensure that the `bidToken` is a valid ERC20 token and that the Execution Environment has approved the Solver contract to transfer the specified amount.
## 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 `SolverBaseInvertBid` contract does not emit custom events, consider emitting events in extended contracts to facilitate easier tracking and monitoring of solver operations.
## Conclusion
The `SolverBaseInvertBid` contract provides a robust and secure foundation for implementing solver operations within the Atlas Protocol, specifically tailored for scenarios where bid values are inverted. By ensuring safety checks, managing bid payments, handling escrow reconciliation, and optionally retrieving bids, 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.