Factory Contract
The Factory contract is the central registry and management system for all trading pairs in the Oyl AMM protocol. It handles pool creation, routing, and protocol-wide operations.
Contract Overview
The Factory contract serves as:
- Pool Registry: Maintains a list of all trading pairs
- Pool Creator: Deploys new pool contracts
- Router: Handles multi-hop swaps and liquidity operations
- Fee Manager: Collects protocol fees
Core Functions
Pool Management
InitFactory
Initializes the factory with required parameters:
#[opcode(0)]
InitFactory {
pool_factory_id: u128,
beacon_id: AlkaneId,
}
CreateNewPool
Creates a new trading pair:
#[opcode(1)]
CreateNewPool {
token_a: AlkaneId,
token_b: AlkaneId,
amount_a: u128,
amount_b: u128,
}
This function:
- Deploys a new pool contract
- Registers the pool in the factory
- Sets up initial pool parameters
- Provides initial liquidity
FindExistingPoolId
Finds the pool ID for a token pair:
#[opcode(2)]
FindExistingPoolId {
alkane_a: AlkaneId, // First token
alkane_b: AlkaneId, // Second token
}
Returns the pool ID if it exists, or creates a new pool if it doesn't.
Pool Information
GetAllPools
Returns a list of all pools:
#[opcode(3)]
#[returns(Vec<u8>)]
GetAllPools
Example script to decode the output
function parseHexData(hex) {
if (hex.startsWith("0x")) {
hex = hex.slice(2);
}
const buf = Buffer.from(hex, "hex");
// 获取 pool 数量(前 16 字节,小端,取最低字节)
const poolCount = buf.readUIntLE(0, 1);
const pools = [];
let offset = 16;
for (let i = 0; i < poolCount; i++) {
// 读取 block(16 字节,小端)
const blockLE = buf.slice(offset, offset + 16);
const blockLEBigInt = bufferToBigIntLE(blockLE);
offset += 16;
// 读取 tx(16 字节,小端)
const txLE = buf.slice(offset, offset + 16);
const txBigInt = bufferToBigIntLE(txLE);
offset += 16;
pools.push({
block: blockLEBigInt.toString(),
tx: txBigInt.toString(),
});
}
return {
poolCount,
pools,
};
}
function bufferToBigIntLE(buffer) {
let result = 0n;
for (let i = buffer.length - 1; i >= 0; i--) {
result = (result << 8n) + BigInt(buffer[i]);
}
return result;
}
GetNumPools
Returns the total number of pools:
#[opcode(4)]
#[returns(Vec<u8>)]
GetNumPools
Configuration
SetPoolFactoryId
Updates the pool factory ID:
#[opcode(7)]
SetPoolFactoryId {
pool_factory_id: u128
}
This function is restricted to authorized users only.
Liquidity Operations
AddLiquidity
Adds liquidity to a trading pair:
#[opcode(11)]
AddLiquidity {
token_a: AlkaneId, // First token
token_b: AlkaneId, // Second token
amount_a_desired: u128, // Desired amount of token A
amount_b_desired: u128, // Desired amount of token B
amount_a_min: u128, // Minimum amount of token A
amount_b_min: u128, // Minimum amount of token B
deadline: u128, // Transaction deadline in block height
}
The function:
- Finds or creates the pool for the token pair
- Calculates optimal amounts based on current reserves
- Transfers tokens to the pool
- Mints LP tokens to the user
Burn (Remove Liquidity)
Removes liquidity from a trading pair:
#[opcode(12)]
Burn {
token_a: AlkaneId, // First token
token_b: AlkaneId, // Second token
liquidity: u128, // Amount of LP tokens to burn
amount_a_min: u128, // Minimum amount of token A to receive
amount_b_min: u128, // Minimum amount of token B to receive
deadline: u128, // Transaction deadline in block height
}
Trading Operations
SwapExactTokensForTokens
Swaps an exact amount of input tokens for output tokens:
#[opcode(13)]
SwapExactTokensForTokens {
path: Vec<AlkaneId>, // Token path for the swap
amount_in: u128, // The amount of input tokens to send
amount_out_min: u128, // Minimum output amount
deadline: u128, // Transaction deadline in block height
}
SwapTokensForExactTokens
Swaps tokens to get an exact amount of output tokens:
#[opcode(14)]
SwapTokensForExactTokens {
path: Vec<AlkaneId>, // Token path for the swap
amount_out: u128, // Exact output amount desired
amount_in_max: u128, // Maximum input amount
deadline: u128, // Transaction deadline in block height
}
SwapExactTokensForTokensImplicit
Swaps an exact amount of input tokens for output tokens, where the input amount is implicitly determined by the value of the alkanes sent with the call.
#[opcode(29)]
SwapExactTokensForTokensImplicit {
path: Vec<AlkaneId>,
amount_out_min: u128,
deadline: u128, // Transaction deadline in block height
}
Fee Management
CollectFees
Collects protocol fees from a specific pool:
#[opcode(10)]
CollectFees {
pool_id: AlkaneId
}
This function:
- Calculates accumulated protocol fees
- Transfers fees to the protocol treasury
- Updates pool fee tracking
Access Control
Authentication
The Factory contract implements authentication mechanisms:
- Critical functions require proper authorization
- Uses the Alkanes authentication system
- Protects against unauthorized access
Permissions
Different functions have different permission levels:
- Public: Pool queries, swaps
- User: Liquidity operations
- Admin: Configuration changes, fee collection
The Factory contract is the main entry point for most Oyl AMM operations, providing a unified interface for pool management, liquidity operations, and trading.