A modular Solidity-based solution handling asset swaps within the Frak ecosystem. Streamlined, secure, and designed with developers in mind.
- Features
- Contract Structure
- How It Works
- Supported Operations
- Installation and Usage
- Security Audits
- Credits & Acknowledgments
- Authors
- License
- Pool Per Contract Mechanism: Enhanced flexibility by allowing a dedicated pool for each contract.
- In-Memory Accounting: Optimized performance by handling account balances and transactions in memory.
- EIP-2612 Permit Signature Support: Integrated support for EIP-2612 permit signatures, enabling better user experience and security.
- Unified Token Abstraction: With the new
TokenLib.sol
, seamlessly manage both ERC-20 tokens and native chain tokens using a singular user-defined value type.
.
βββ MonoPool.sol - Contract containing a single pool
βββ Ops.sol - Contains the list of all available operations (Ops)
βββ lib
β βββ AccounterLib.sol - Library containing the in-memory accounting logic (account changes, get changes, reset changes etc)
β βββ PoolLib.sol - Related to all the pool logic (add/rm liquidity, trigger swap)
β βββ SwapLib.sol - Library containing the stuff related to swap operation computation
β βββ TokenLib.sol - Unified token type for ERC-20 and native tokens abstraction
βββ encoder
β βββ DecoderLib.sol - Helps decode data for each operation
β βββ EncoderLib.sol - Assists off-chain users to build their program. Not for on-chain use. (Gas inefficient)
Always remember: Use EncoderLib
exclusively in off-chain scenarios for optimal gas efficiency.
- The pool employs an internal accounting system to keep track of balance changes for two specific tokens, namely
token0
andtoken1
, during the course of a transaction block (flash execution). This seamless tracking is possible thanks to the abstraction provided by theTokenLib.sol
. - Instead of making changes to the Ethereum state immediately, the contract first tracks net balance changes internally.
- After all operations have been executed, the contract then applies the final net changes to the actual balances of
token0
andtoken1
at the end of the transaction block. - This approach aims to minimize gas usage, as frequent state changes (storage operations) are generally costly in terms of gas.
- With the new
TokenLib.sol
, the system has a built-in abstraction layer to handle both ERC-20 tokens and native tokens (represented by the address 0). - This allows for seamless transfers and balance checks for both ERC-20 and native chain tokens.
- Whether interacting with ERC-20's
transfer()
andbalanceOf()
or native chain operations, the underlying logic remains abstracted, reducing complexity and potential errors.
- Interactions with the pools are facilitated via the
execute(bytes program)
function. - The "program" is essentially a serialized set of operations and follows a specific structure:
- Every operation within this program comprises:
- An 8-bit operation, spanning 1 byte.
- Data pertaining to the opcode, spanning 'n' bytes.
- Every operation within this program comprises:
- This encoding method ensures minimal calldata size, given that each operation might need different data amounts.
- An 8-bit operation specifier contains two parts:
- The first 4 bits (half) represent the operation ID (Op Code).
- The latter 4 bits represent flags.
- Thus, there's the potential for up to 16 primary operations. Each can interpret 4 additional flags.
- Parameters are always packed tightly.
- Encoding of individual operations can be found in the
EncoderLib
. - Note: Operation names are from the pool's viewpoint. For example, "send" means the pool is transferring assets to an external party.
- Flags are used to modify or extend the behavior of an operation.
- Masks, like
SWAP_DIR = 0x01
, are used to work with flags. For example:- To set a flag on an operation:
operationCode |= SWAP_DIR
- To check if a flag is set on an operation:
operationCode & SWAP_DIR != 0
- To set a flag on an operation:
The Ops
library delineates all the operations permissible by the swap contracts. These operations are enumerated as constants.
-
SWAP Operation: Used for swapping transactions.
- Operation Code:
SWAP = 0x00
- Direction Flag:
- Extracts the direction of the operation.
SWAP_DIR = 0x01
- Deadline Flag:
- Add a deadline to the swap operation.
SWAP_DEADLINE = 0x02
- Operation Code:
-
SEND_ALL Operation: Allows the pool to send all tokens to the user.
- Operation Code:
SEND_ALL = 0x10
- Operation Code:
-
RECEIVE_ALL Operation: Allows the user to send all tokens to the pool.
- Operation Code:
RECEIVE_ALL = 0x20
- Operation Code:
-
SEND Operation: Allows the pool to send tokens to the user.
- Operation Code:
SEND = 0x30
- Operation Code:
-
RECEIVE Operation: Allows the user to send tokens to the pool.
- Operation Code:
RECEIVE = 0x40
- Operation Code:
-
PERMIT_WITHDRAW_VIA_SIG Operation: Enables permit functionality using EIP-2612.
- Operation Code:
PERMIT_WITHDRAW_VIA_SIG = 0x50
- Operation Code:
-
ADD_LIQ Operation: Adds liquidity to the pool.
- Operation Code:
ADD_LIQ = 0x60
- Operation Code:
-
RM_LIQ Operation: Removes liquidity from the pool.
- Operation Code:
RM_LIQ = 0x70
- Operation Code:
-
CLAIM_ALL_FEES Operation: Allows the operator to claim all fees.
- Operation Code:
CLAIM_ALL_FEES = 0x80
- Operation Code:
-
Minimum Token Amount:
ALL_MIN_BOUND = 0x01
(with mask0001
)
-
Maximum Token Amount:
ALL_MAX_BOUND = 0x02
(with mask0010
)
For an intricate understanding, consider examining the Ops
library's source code.
To compile and test the contracts, we utilize foundry. Make sure to familiarize yourself with its environment and setup.
To build all the smart contracts, run:
forge build
To execute all the unit tests, use:
forge test
To view the coverage of unit tests, run:
forge coverage
To assess the differences in gas consumption based on the latest changes, execute:
forge snapshot --diff
To update the snapshot report, run:
forge snapshot
Before running Slither for code analysis, ensure you have it installed. If not, refer to the official Slither Documentation.
Once installed, use the following command to analyze the code:
slither --config-file tools/slither.config.json .
For transparency and trust, each security audit conducted on our contracts is meticulously documented. We provide details of the auditors, the context or purpose of the audit, the date, and the files covered. Below is a summary of all the audits conducted:
-
Audit by nisedo - 20/08/2023
- Context: General overview of the project.
- Files Covered:
MonoPool.sol
- View Audit Report
-
Audit by Mlome - 24/08/2023
- Context: Brief security audit of the project.
- Files Covered: ALL
- View Audit Report
-
Audit by Beirao - 05/09/2023
- Context: Global security audit of the project.
- Files Covered: ALL
- View Audit Report
We owe a debt of gratitude to the foundational work done by Philogy. Our implementation, while unique, has been greatly inspired by or derives from their stellar work on the singleton-swapper repository.
- KONFeature - Profile - Main Author and Developer.
- Philogy - Profile - Credits for foundational work.
This project is licensed under the AGPL-3.0-only License. Portions of the codebase are derived or inspired by projects under their respective licenses. Always ensure compatibility when integrating or modifying the code.