ownership & killable

This commit is contained in:
tim
2025-10-19 13:35:33 -04:00
parent 5aa0032be0
commit d55be28cba
18 changed files with 364 additions and 176 deletions

View File

@@ -18,27 +18,33 @@ import {ReentrancyGuard} from "../lib/openzeppelin-contracts/contracts/utils/Ree
import {SafeERC20} from "../lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol";
import {IERC3156FlashLender} from "../lib/openzeppelin-contracts/contracts/interfaces/IERC3156FlashLender.sol";
import {NativeWrapper} from "./NativeWrapper.sol";
import {OwnableExternal} from "./OwnableExternal.sol";
/// @title PartyPool - LMSR-backed multi-asset pool with LP ERC20 token
/// @notice A multi-asset liquidity pool backed by the LMSRStabilized pricing model.
/// The pool issues an ERC20 LP token representing proportional ownership.
/// It supports:
/// - Proportional minting and burning of LP _tokens,
/// - Single-token mint (swapMint) and single-asset withdrawal (burnSwap),
/// - Proportional minting and burning of LP tokens,
/// - Exact-input swaps and swaps-to-price-limits,
/// - Flash loans via a callback interface.
/// - Single-token mint (swapMint) and single-asset withdrawal (burnSwap),
/// - ERC-3156 flash loans
///
/// @dev The contract stores per-token uint "_bases" used to scale token units into the internal Q64.64
/// representation used by the LMSR library. Cached on-chain uint balances are kept to reduce balanceOf calls.
/// @dev The contract stores per-token uint `_bases` used to scale token units into the internal Q64.64
/// representation used by the LMSR library. Cached on-chain uint balances are kept to reduce balanceOf() calls.
/// The contract uses ceiling/floor rules described in function comments to bias rounding in favor of the pool
/// (i.e., floor outputs to users, ceil inputs/fees where appropriate).
contract PartyPool is PartyPoolBase, ERC20External, IPartyPool {
/// (i.e., floor outputs to users, ceil inputs/fees where appropriate). Mutating methods have re-entrancy locks.
/// The contract may be "killed" by the admin in case any security issue is discovered, in which case all swaps and
/// mints are disabled, and only the burn() method remains functional to allow LP's to withdraw their assets.
contract PartyPool is PartyPoolBase, OwnableExternal, ERC20External, IPartyPool {
using ABDKMath64x64 for int128;
using LMSRStabilized for LMSRStabilized.State;
using SafeERC20 for IERC20;
receive() external payable {}
/// @notice If true, the vault has been disabled by the owner and only burns (withdrawals) are allowed.
function killed() external view returns (bool) { return _killed; }
function wrapperToken() external view returns (NativeWrapper) { return WRAPPER_TOKEN; }
/// @notice Liquidity parameter κ (Q64.64) used by the LMSR kernel: b = κ * S(q)
@@ -90,6 +96,7 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool {
function LMSR() external view returns (LMSRStabilized.State memory) { return _lmsr; }
/// @param owner_ Admin account that can disable the vault using kill()
/// @param name_ LP token name
/// @param symbol_ LP token symbol
/// @param tokens_ token addresses (n)
@@ -100,6 +107,7 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool {
/// @param swapImpl_ address of the SwapMint implementation contract
/// @param mintImpl_ address of the Mint implementation contract
constructor(
address owner_,
string memory name_,
string memory symbol_,
IERC20[] memory tokens_,
@@ -114,8 +122,10 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool {
PartyPoolMintImpl mintImpl_
)
PartyPoolBase(wrapperToken_)
OwnableExternal(owner_)
ERC20External(name_, symbol_)
{
require(owner_ != address(0));
require(tokens_.length > 1, "Pool: need >1 asset");
require(tokens_.length == bases_.length, "Pool: lengths mismatch");
_tokens = tokens_;
@@ -149,6 +159,11 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool {
_protocolFeesOwed = new uint256[](n);
}
/// @notice If a security problem is found, the vault owner may call this function to permanently disable swap and
/// mint functionality, leaving only burns (withdrawals) working.
function kill() external onlyOwner {
_killed = true;
}
/* ----------------------
Initialization / Mint / Burn (LP token managed)
@@ -225,7 +240,7 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool {
int128 limitPrice,
uint256 deadline,
bool unwrap
) external payable native nonReentrant returns (uint256 amountIn, uint256 amountOut, uint256 fee) {
) external payable native nonReentrant killable returns (uint256 amountIn, uint256 amountOut, uint256 fee) {
require(deadline == 0 || block.timestamp <= deadline, "swap: deadline exceeded");
// Compute amounts using the same path as views
@@ -425,7 +440,7 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool {
address tokenAddr,
uint256 amount,
bytes calldata data
) external nonReentrant returns (bool)
) external nonReentrant killable returns (bool)
{
IERC20 token = IERC20(tokenAddr);
require(amount <= token.balanceOf(address(this)));