PrivatePool
Inherits: ERC721TokenReceiver
Author: out.eth (@outdoteth)
A private pool is a an NFT AMM controlled by a single owner with concentrated liquidity, custom fee rates, stolen NFT filtering, custom NFT weightings, royalty support, and flash loans. You can create a pool and change these parameters to your liking. Deposit NFTs and base tokens (or ETH) into the pool to enable trading. Earn fees on each trade.
State Variables
baseToken
The address of the base ERC20 token.
nft
The address of the nft.
changeFee
The change/flash fee to 4 decimals of precision. For example, 0.0025 ETH = 25. 500 USDC = 5_000_000.
feeRate
The buy/sell fee rate (in basis points) 200 = 2%
initialized
Whether or not the pool has been initialized.
payRoyalties
Whether or not the pool pays royalties to the NFT creator on each trade.
useStolenNftOracle
Whether or not the pool uses the stolen NFT oracle to check if an NFT is stolen.
virtualBaseTokenReserves
The virtual base token reserves used in the xy=k invariant. Changing this will change the liquidity depth and price of the pool.
virtualNftReserves
The virtual nft reserves used in the xy=k invariant. Changing this will change the liquidity depth and price of the pool.
The virtual NFT reserves that a user sets. If it's desired to set the reserves to match 16 NFTs then the virtual reserves should be set to 16e18. If weights are enabled by setting the merkle root to be non-zero then the virtual reserves should be set to the sum of the weights of the NFTs; where floor NFTs all have a weight of 1e18. A rarer NFT may have a weight of 2.3e18 if it's 2.3x more valuable than a floor.
merkleRoot
The merkle root of all the token weights in the pool. If the merkle root is set to bytes32(0) then all NFTs are set to have a weight of 1e18.
stolenNftOracle
The NFT oracle to check if an NFT is stolen.
factory
The factory contract that created this pool.
royaltyRegistry
The royalty registry from manifold.xyz.
Functions
onlyOwner
receive
constructor
*This is only called when the base implementation contract is deployed. The following immutable parameters are set:
factory: The address of the factory contract
royaltyRegistry: The address of the royalty registry from manifold.xyz
stolenNftOracle: The address of the stolen NFT oracle These are all stored in immutable storage, which enables all minimal proxy contracts to read them without incurring additional deployment costs and re-initializing them at point of creation in the factory contract.*
initialize
Initializes the private pool and sets the initial parameters. Should only be called once by the factory.
Parameters
_baseToken
address
The address of the base token
_nft
address
The address of the NFT
_virtualBaseTokenReserves
uint128
The virtual base token reserves
_virtualNftReserves
uint128
The virtual NFT reserves
_changeFee
uint56
_feeRate
uint16
The fee rate (in basis points) 200 = 2%
_merkleRoot
bytes32
The merkle root
_useStolenNftOracle
bool
Whether or not the pool uses the stolen NFT oracle to check if an NFT is stolen
_payRoyalties
bool
buy
Buys NFTs from the pool, paying with base tokens from the caller. Then transfers the bought NFTs to the caller. The net cost depends on the current price, fee rate and assigned NFT weights.
DO NOT call this function directly unless you know what you are doing. Instead, use a wrapper contract that will check the max input amount and revert if the slippage is too high.
Parameters
tokenIds
uint256[]
The token IDs of the NFTs to buy.
tokenWeights
uint256[]
The weights of the NFTs to buy.
proof
MerkleMultiProof
The merkle proof for the weights of each NFT to buy.
Returns
netInputAmount
uint256
The amount of base tokens spent inclusive of fees.
feeAmount
uint256
The amount of base tokens spent on fees.
protocolFeeAmount
uint256
sell
Sells NFTs into the pool and transfers base tokens to the caller. NFTs are transferred from the caller to the pool. The net sale amount depends on the current price, fee rate and assigned NFT weights.
DO NOT call this function directly unless you know what you are doing. Instead, use a wrapper contract that will check the min output amount and revert if the slippage is too high.
Parameters
tokenIds
uint256[]
The token IDs of the NFTs to sell.
tokenWeights
uint256[]
The weights of the NFTs to sell.
proof
MerkleMultiProof
The merkle proof for the weights of each NFT to sell.
stolenNftProofs
Message.IStolenNftOracle[]
The proofs that show each NFT is not stolen.
Returns
netOutputAmount
uint256
The amount of base tokens received inclusive of fees.
feeAmount
uint256
The amount of base tokens to pay in fees.
protocolFeeAmount
uint256
change
Changes a set of NFTs that the caller owns for another set of NFTs in the pool. The caller must approve the pool to transfer the NFTs. The sum of the caller's NFT weights must be less than or equal to the sum of the output pool NFTs weights. The caller must also pay a fee depending the net input weight and change fee amount.
Parameters
inputTokenIds
uint256[]
The token IDs of the NFTs to change.
inputTokenWeights
uint256[]
The weights of the NFTs to change.
inputProof
MerkleMultiProof
The merkle proof for the weights of each NFT to change.
stolenNftProofs
Message.IStolenNftOracle[]
The proofs that show each input NFT is not stolen.
outputTokenIds
uint256[]
The token IDs of the NFTs to receive.
outputTokenWeights
uint256[]
The weights of the NFTs to receive.
outputProof
MerkleMultiProof
The merkle proof for the weights of each NFT to receive.
execute
Executes a transaction from the pool account to a target contract. The caller must be the owner of the pool. This allows for use cases such as claiming airdrops.
Parameters
target
address
The address of the target contract.
data
bytes
The data to send to the target contract.
Returns
<none>
bytes
returnData The return data of the transaction.
deposit
Deposits base tokens and NFTs into the pool. The caller must approve the pool to transfer their NFTs and base tokens.
DO NOT call this function directly unless you know what you are doing. Instead, use a wrapper contract that will check the current price is within the desired bounds.
Parameters
tokenIds
uint256[]
The token IDs of the NFTs to deposit.
baseTokenAmount
uint256
The amount of base tokens to deposit.
withdraw
Withdraws NFTs and tokens from the pool. Can only be called by the owner of the pool.
Parameters
_nft
address
The address of the NFT.
tokenIds
uint256[]
The token IDs of the NFTs to withdraw.
token
address
The address of the token to withdraw.
tokenAmount
uint256
The amount of tokens to withdraw.
setVirtualReserves
Sets the virtual base token reserves and virtual NFT reserves. Can only be called by the owner of the pool. These parameters affect the price and liquidity depth of the pool.
Parameters
newVirtualBaseTokenReserves
uint128
The new virtual base token reserves.
newVirtualNftReserves
uint128
The new virtual NFT reserves.
setMerkleRoot
Sets the merkle root. Can only be called by the owner of the pool. The merkle root is used to validate the NFT weights.
Parameters
newMerkleRoot
bytes32
The new merkle root.
setFeeRate
Sets the fee rate. Can only be called by the owner of the pool. The fee rate is used to calculate the fee amount when swapping or changing NFTs. The fee rate is in basis points (1/100th of a percent). For example, 10_000 == 100%, 200 == 2%, 1 == 0.01%.
Parameters
newFeeRate
uint16
The new fee rate (in basis points)
setUseStolenNftOracle
Sets the whether or not to use the stolen NFT oracle. Can only be called by the owner of the pool. The stolen NFT oracle is used to check if an NFT is stolen.
Parameters
newUseStolenNftOracle
bool
The new use stolen NFT oracle flag.
setPayRoyalties
Sets the pay royalties flag. Can only be called by the owner of the pool. If royalties are enabled then the pool will pay royalties when buying or selling NFTs.
Parameters
newPayRoyalties
bool
The new pay royalties flag.
setAllParameters
Updates all parameter settings in one go.
Parameters
newVirtualBaseTokenReserves
uint128
The new virtual base token reserves.
newVirtualNftReserves
uint128
The new virtual NFT reserves.
newMerkleRoot
bytes32
The new merkle root.
newFeeRate
uint16
The new fee rate (in basis points)
newUseStolenNftOracle
bool
The new use stolen NFT oracle flag.
newPayRoyalties
bool
The new pay royalties flag.
flashLoan
Executes a flash loan.
Parameters
receiver
IERC3156FlashBorrower
The receiver of the flash loan.
token
address
The address of the NFT contract.
tokenId
uint256
The ID of the NFT.
data
bytes
The data to pass to the receiver.
Returns
<none>
bool
success Whether or not the flash loan was successful.
sumWeightsAndValidateProof
Sums the weights of each NFT and validates that the weights are correct by verifying the merkle proof.
Parameters
tokenIds
uint256[]
The token IDs of the NFTs to sum the weights for.
tokenWeights
uint256[]
The weights of each NFT in the token IDs array.
proof
MerkleMultiProof
The merkle proof for the weights of each NFT.
Returns
<none>
uint256
sum The sum of the weights of each NFT.
_getRoyalty
Gets the royalty and recipient for a given NFT and sale price. Looks up the royalty info from the manifold registry.
Parameters
tokenId
uint256
The token ID of the NFT.
salePrice
uint256
The sale price of the NFT.
Returns
royaltyFee
uint256
The royalty fee to pay.
recipient
address
The address to pay the royalty fee to.
buyQuote
Returns the required input of buying a given amount of NFTs inclusive of the fee which is dependent on the currently set fee rate.
Parameters
outputAmount
uint256
The amount of NFTs to buy multiplied by 1e18.
Returns
netInputAmount
uint256
The required input amount of base tokens inclusive of the fee.
feeAmount
uint256
The fee amount.
protocolFeeAmount
uint256
sellQuote
Returns the output amount of selling a given amount of NFTs inclusive of the fee which is dependent on the currently set fee rate.
Parameters
inputAmount
uint256
The amount of NFTs to sell multiplied by 1e18.
Returns
netOutputAmount
uint256
The output amount of base tokens inclusive of the fee.
feeAmount
uint256
The fee amount.
protocolFeeAmount
uint256
changeFeeQuote
Returns the fee required to change a given amount of NFTs. The fee is based on the current changeFee (which contains 4 decimals of precision) multiplied by some exponent depending on the base token decimals.
Parameters
inputAmount
uint256
The amount of NFTs to change multiplied by 1e18.
Returns
feeAmount
uint256
The fee amount.
protocolFeeAmount
uint256
The protocol fee amount.
price
Returns the price of the pool to 18 decimals of accuracy.
Returns
<none>
uint256
price The price of the pool.
flashFee
Returns the fee required to flash swap a given NFT.
Returns
<none>
uint256
feeAmount The fee amount.
flashFeeToken
Returns the token that is used to pay the flash fee.
availableForFlashLoan
Returns whether or not an NFT is available for a flash loan.
Parameters
token
address
The address of the NFT contract.
tokenId
uint256
The ID of the NFT.
Returns
<none>
bool
available Whether or not the NFT is available for a flash loan.
Events
Initialize
Buy
Sell
Deposit
Withdraw
Change
SetVirtualReserves
SetMerkleRoot
SetFeeRate
SetUseStolenNftOracle
SetPayRoyalties
Errors
AlreadyInitialized
Unauthorized
InvalidEthAmount
InvalidMerkleProof
InsufficientInputWeight
FeeRateTooHigh
NotAvailableForFlashLoan
FlashLoanFailed
InvalidRoyaltyFee
Structs
MerkleMultiProof
Merkle proof input for a sparse merkle multi proof. It can be generated with a library like: https://github.com/OpenZeppelin/merkle-tree#treegetmultiproof
Last updated