PartyPlanner; chain.json
This commit is contained in:
183
src/PartyPlanner.sol
Normal file
183
src/PartyPlanner.sol
Normal file
@@ -0,0 +1,183 @@
|
||||
// SPDX-License-Identifier: UNLICENSED
|
||||
pragma solidity ^0.8.30;
|
||||
|
||||
import "./IPartyPlanner.sol";
|
||||
import "./PartyPool.sol";
|
||||
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
||||
|
||||
/// @title PartyPlanner
|
||||
/// @notice Factory contract for creating and tracking PartyPool instances
|
||||
contract PartyPlanner is IPartyPlanner {
|
||||
using SafeERC20 for IERC20;
|
||||
int128 private constant FIXED_ONE_64x64 = int128(1) << 64;
|
||||
|
||||
// On-chain pool indexing
|
||||
PartyPool[] private _allPools;
|
||||
IERC20[] private _allTokens;
|
||||
mapping(PartyPool => bool) private _poolSupported;
|
||||
mapping(IERC20 => bool) private _tokenSupported;
|
||||
mapping(IERC20 => PartyPool[]) private _poolsByToken;
|
||||
|
||||
/// @inheritdoc IPartyPlanner
|
||||
function createPool(
|
||||
// Pool constructor args
|
||||
string memory name_,
|
||||
string memory symbol_,
|
||||
IERC20[] memory _tokens,
|
||||
uint256[] memory _bases,
|
||||
int128 _tradeFrac,
|
||||
int128 _targetSlippage,
|
||||
uint256 _swapFeePpm,
|
||||
uint256 _flashFeePpm,
|
||||
bool _stable,
|
||||
// Initial deposit information
|
||||
address payer,
|
||||
address receiver,
|
||||
uint256[] memory initialDeposits,
|
||||
uint256 initialLpAmount,
|
||||
uint256 deadline
|
||||
) external returns (PartyPool pool, uint256 lpAmount) {
|
||||
// Validate inputs
|
||||
require(deadline == 0 || block.timestamp <= deadline, "Planner: deadline exceeded");
|
||||
require(_tokens.length == initialDeposits.length, "Planner: tokens and deposits length mismatch");
|
||||
require(payer != address(0), "Planner: payer cannot be zero address");
|
||||
require(receiver != address(0), "Planner: receiver cannot be zero address");
|
||||
|
||||
// Validate fixed-point fractions: must be less than 1.0 in 64.64 fixed-point
|
||||
require(_tradeFrac < FIXED_ONE_64x64, "Planner: tradeFrac must be < 1 (64.64)");
|
||||
require(_targetSlippage < FIXED_ONE_64x64, "Planner: targetSlippage must be < 1 (64.64)");
|
||||
|
||||
// Create a new PartyPool instance
|
||||
pool = new PartyPool(
|
||||
name_,
|
||||
symbol_,
|
||||
_tokens,
|
||||
_bases,
|
||||
_tradeFrac,
|
||||
_targetSlippage,
|
||||
_swapFeePpm,
|
||||
_flashFeePpm,
|
||||
_stable
|
||||
);
|
||||
|
||||
_allPools.push(pool);
|
||||
_poolSupported[pool] = true;
|
||||
|
||||
// Track tokens and populate mappings
|
||||
for (uint256 i = 0; i < _tokens.length; i++) {
|
||||
IERC20 token = _tokens[i];
|
||||
|
||||
// Add token to _allTokens if not already present
|
||||
if (!_tokenSupported[token]) {
|
||||
_allTokens.push(token);
|
||||
_tokenSupported[token] = true;
|
||||
}
|
||||
|
||||
// Add pool to _poolsByToken mapping
|
||||
_poolsByToken[token].push(pool);
|
||||
}
|
||||
|
||||
emit PartyStarted(pool, name_, symbol_, _tokens);
|
||||
|
||||
// Transfer initial tokens from payer to the pool
|
||||
for (uint256 i = 0; i < _tokens.length; i++) {
|
||||
if (initialDeposits[i] > 0) {
|
||||
IERC20(_tokens[i]).safeTransferFrom(payer, address(pool), initialDeposits[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Call mint on the new pool to initialize it with the transferred tokens
|
||||
lpAmount = pool.initialMint(receiver, initialLpAmount);
|
||||
}
|
||||
|
||||
/// @inheritdoc IPartyPlanner
|
||||
function getPoolSupported(address pool) external view returns (bool) {
|
||||
return _poolSupported[PartyPool(pool)];
|
||||
}
|
||||
|
||||
/// @inheritdoc IPartyPlanner
|
||||
function poolCount() external view returns (uint256) {
|
||||
return _allPools.length;
|
||||
}
|
||||
|
||||
/// @inheritdoc IPartyPlanner
|
||||
function getAllPools(uint256 offset, uint256 limit) external view returns (PartyPool[] memory pools) {
|
||||
uint256 totalPools = _allPools.length;
|
||||
|
||||
// If offset is beyond array bounds, return empty array
|
||||
if (offset >= totalPools) {
|
||||
return new PartyPool[](0);
|
||||
}
|
||||
|
||||
// Calculate actual number of pools to return (respecting bounds)
|
||||
uint256 itemsToReturn = (offset + limit > totalPools) ? (totalPools - offset) : limit;
|
||||
|
||||
// Create result array of appropriate size
|
||||
pools = new PartyPool[](itemsToReturn);
|
||||
|
||||
// Fill the result array
|
||||
for (uint256 i = 0; i < itemsToReturn; i++) {
|
||||
pools[i] = _allPools[offset + i];
|
||||
}
|
||||
|
||||
return pools;
|
||||
}
|
||||
|
||||
/// @inheritdoc IPartyPlanner
|
||||
function tokenCount() external view returns (uint256) {
|
||||
return _allTokens.length;
|
||||
}
|
||||
|
||||
/// @inheritdoc IPartyPlanner
|
||||
function getAllTokens(uint256 offset, uint256 limit) external view returns (address[] memory tokens) {
|
||||
uint256 totalTokens = _allTokens.length;
|
||||
|
||||
// If offset is beyond array bounds, return empty array
|
||||
if (offset >= totalTokens) {
|
||||
return new address[](0);
|
||||
}
|
||||
|
||||
// Calculate actual number of tokens to return (respecting bounds)
|
||||
uint256 itemsToReturn = (offset + limit > totalTokens) ? (totalTokens - offset) : limit;
|
||||
|
||||
// Create result array of appropriate size
|
||||
tokens = new address[](itemsToReturn);
|
||||
|
||||
// Fill the result array
|
||||
for (uint256 i = 0; i < itemsToReturn; i++) {
|
||||
tokens[i] = address(_allTokens[offset + i]);
|
||||
}
|
||||
|
||||
return tokens;
|
||||
}
|
||||
|
||||
/// @inheritdoc IPartyPlanner
|
||||
function poolsByTokenCount(IERC20 token) external view returns (uint256) {
|
||||
return _poolsByToken[token].length;
|
||||
}
|
||||
|
||||
/// @inheritdoc IPartyPlanner
|
||||
function getPoolsByToken(IERC20 token, uint256 offset, uint256 limit) external view returns (PartyPool[] memory pools) {
|
||||
PartyPool[] storage tokenPools = _poolsByToken[token];
|
||||
uint256 totalPools = tokenPools.length;
|
||||
|
||||
// If offset is beyond array bounds, return empty array
|
||||
if (offset >= totalPools) {
|
||||
return new PartyPool[](0);
|
||||
}
|
||||
|
||||
// Calculate actual number of pools to return (respecting bounds)
|
||||
uint256 itemsToReturn = (offset + limit > totalPools) ? (totalPools - offset) : limit;
|
||||
|
||||
// Create result array of appropriate size
|
||||
pools = new PartyPool[](itemsToReturn);
|
||||
|
||||
// Fill the result array
|
||||
for (uint256 i = 0; i < itemsToReturn; i++) {
|
||||
pools[i] = tokenPools[offset + i];
|
||||
}
|
||||
|
||||
return pools;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user