Merge pull request #71 from propeller-heads/dc/ENG-3521-add-iswap-executor

feat: Add ISwapExecutor and docs
This commit is contained in:
dianacarvalho1
2024-08-23 12:58:13 +01:00
committed by GitHub
5 changed files with 96 additions and 1 deletions

View File

@@ -25,3 +25,8 @@ While VM integration is certainly the quickest and probably most accessible one
For indexing purposes, it is required that you provide a [substreams](https://substreams.streamingfast.io/) package that emits a specified set of messages. If your protocol already has a [substreams package](https://github.com/messari/substreams) for indexing implemented, you can adjust it to emit the required messages.
**VM Integration** Currently the only supported integration is for EVM protocols in order to complement the Solidity protocol logic. [**Read more here.**](https://github.com/propeller-heads/propeller-venue-lib/blob/main/docs/indexing/vm-integration/README.md) **Custom Entity Integration** Coming soon, this integration will complement the upcoming native Rust protocol logic.
### Execution
For execution purposes, the implementation of the `SwapExecutor` interface is required. Without this component, trades cannot be executed on-chain, making it a critical part of the integration.
The `SwapExecutor` is responsible for performing swaps by interacting with the underlying liquidity pools, handling token approvals, managing input/output amounts, and ensuring gas-efficient and secure execution. Each protocol must implement its own `SwapExecutor`, tailored to its specific logic and requirements.

View File

@@ -15,3 +15,6 @@
- [VM Integration](indexing/vm-integration/README.md)
- [Native Integration](indexing/native-integration.md)
- [Reserved Attributes](indexing/reserved-attributes.md)
## Execution
- [Swap Executor](execution/swap-executor.md)

View File

@@ -0,0 +1,39 @@
# Implementing a SwapExecutor for a Protocol
## Overview
The `ISwapExecutor` interface is designed to perform swaps on a liquidity pool.
It allows for flexible interaction by accepting either the amount of the input token or the amount of the output token
as parameters, returning the corresponding swapped amount.
This interface is essential for creating a `SwapExecutor` specific to a protocol.
## Key Methods
- **swap(uint256 givenAmount, bytes calldata data)**
- **Purpose**: To perform a token swap, either specifying the input amount to get the output amount or vice versa.
- **Parameters**:
- `givenAmount`: The amount of the token (input or output) for the swap.
- `data`: Encoded information necessary for the swap (e.g., pool address, token addresses - depends on the protocol).
- **Returns**: The amount of the token swapped.
## Implementation Steps
1. **Define Protocol-Specific Logic**: Implement the `swap` function to interact with the protocol's liquidity pool.
Use the `data` parameter to encode necessary information like pool and token addresses.
2. **Handling Input and Output**: Depending on the provided `givenAmount`, determine whether it's an input or output
swap. Calculate the corresponding swapped amount based on the pool's pricing logic.
3. **Error Handling**: Use `ISwapExecutorErrors` (`InvalidParameterLength` and `UnknownPoolType`) to manage potential
errors, such as invalid parameter lengths or unknown pool types in the swap logic.
4. **Token Approvals**: If the protocol requires token approvals (allowances) before swaps can occur,
manage these approvals within the implementation to ensure smooth execution of the swap.
5. **Token Transfer Support**: Ensure that the implementation supports transferring received tokens to a designated
receiver address, either within the swap function or through an additional transfer step.
6. **Gas Efficiency**: Ensure the implementation is gas-efficient. Strive for optimal performance in the swap logic.
7. **Security Considerations**: Follow common security best practices, such as validating inputs, ensuring proper
access control, and safeguarding against reentrancy attacks.
## Example Implementation
See the example implementation of a `SwapExecutor` for Balancer here (TODO: paste link)

View File

@@ -40,7 +40,7 @@ Following exchanges have been integrated using VM approach:
### Understanding the ISwapAdapter
Read the the documentation of the [Ethereum Solidity interface](ethereum-solidity.md). It describes the functions that need to be implemented as well as the manifest file. Additionally read through the docstring of the [ISwapAdapter.sol](https://github.com/propeller-heads/propeller-venue-lib/blob/main/evm/src/interfaces/ISwapAdapter.sol) interface and the [ISwapAdapterTypes.sol](https://github.com/propeller-heads/propeller-venue-lib/blob/main/evm/src/interfaces/ISwapAdapterTypes.sol) interface which defines the data types and errors used by the adapter interface. You can also generate the documentation locally and the look at the generated documentation in the `./docs` folder:
Read the documentation of the [Ethereum Solidity interface](ethereum-solidity.md). It describes the functions that need to be implemented as well as the manifest file. Additionally read through the docstring of the [ISwapAdapter.sol](https://github.com/propeller-heads/propeller-venue-lib/blob/main/evm/src/interfaces/ISwapAdapter.sol) interface and the [ISwapAdapterTypes.sol](https://github.com/propeller-heads/propeller-venue-lib/blob/main/evm/src/interfaces/ISwapAdapterTypes.sol) interface which defines the data types and errors used by the adapter interface. You can also generate the documentation locally and the look at the generated documentation in the `./docs` folder:
```bash
cd ./evm/

View File

@@ -0,0 +1,48 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.7.5;
import "openzeppelin-contracts/contracts/interfaces/IERC20.sol";
pragma abicoder v2;
interface ISwapExecutor {
/**
* @notice Performs a swap on a liquidity pool.
* @dev This method can either take the amount of the input token or the
* amount
* of the output token that we would like to swap. If called with the amount
* of
* the input token, the amount of the output token will be returned, and
* vice
* versa. Whether it is the input or output that is given, is encoded in the
* data
* parameter.
*
* Note Part of the informal interface is that the executor supports sending
* the received
* tokens to a receiver address. If the underlying smart contract does not
* provide this
* functionality consider adding an additional transfer in the
* implementation.
*
* This function is marked as `payable` to accommodate delegatecalls, which
* can forward
* a potential `msg.value` to it.
*
* @param givenAmount The amount of either the input token or output token
* to swap.
* @param data Data that holds information necessary to perform the swap.
* @return calculatedAmount The amount of either the input token or output
* token
* swapped, depending on the givenAmount inputted.
*/
function swap(uint256 givenAmount, bytes calldata data)
external
payable
returns (uint256 calculatedAmount);
}
interface ISwapExecutorErrors {
error InvalidParameterLength(uint256);
error UnknownPoolType(uint8);
}