Pair.sol

Git Source

Inherits: ERC20, ERC721TokenReceiver

Author: out.eth (@outdoteth)

A pair of an NFT and a base token that can be used to create and trade fractionalized NFTs.

State Variables

CLOSE_GRACE_PERIOD

uint256 public constant CLOSE_GRACE_PERIOD = 7 days;

ONE

uint256 private constant ONE = 1e18;

MINIMUM_LIQUIDITY

uint256 private constant MINIMUM_LIQUIDITY = 100_000;

nft

address public immutable nft;

baseToken

address public immutable baseToken;

merkleRoot

bytes32 public immutable merkleRoot;

lpToken

LpToken public immutable lpToken;

caviar

Caviar public immutable caviar;

closeTimestamp

uint256 public closeTimestamp;

Functions

constructor

constructor(
    address _nft,
    address _baseToken,
    bytes32 _merkleRoot,
    string memory pairSymbol,
    string memory nftName,
    string memory nftSymbol
) ERC20(string.concat(nftName, " fractional token"), string.concat("f", nftSymbol), 18);

add

Adds liquidity to the pair.

function add(
    uint256 baseTokenAmount,
    uint256 fractionalTokenAmount,
    uint256 minLpTokenAmount,
    uint256 minPrice,
    uint256 maxPrice,
    uint256 deadline
) public payable returns (uint256 lpTokenAmount);

Parameters

Name
Type
Description

baseTokenAmount

uint256

The amount of base tokens to add.

fractionalTokenAmount

uint256

The amount of fractional tokens to add.

minLpTokenAmount

uint256

The minimum amount of LP tokens to mint.

minPrice

uint256

The minimum price that the pool should currently be at.

maxPrice

uint256

The maximum price that the pool should currently be at.

deadline

uint256

The deadline before the trade expires.

Returns

Name
Type
Description

lpTokenAmount

uint256

The amount of LP tokens minted.

remove

Removes liquidity from the pair.

function remove(
    uint256 lpTokenAmount,
    uint256 minBaseTokenOutputAmount,
    uint256 minFractionalTokenOutputAmount,
    uint256 deadline
) public returns (uint256 baseTokenOutputAmount, uint256 fractionalTokenOutputAmount);

Parameters

Name
Type
Description

lpTokenAmount

uint256

The amount of LP tokens to burn.

minBaseTokenOutputAmount

uint256

The minimum amount of base tokens to receive.

minFractionalTokenOutputAmount

uint256

The minimum amount of fractional tokens to receive.

deadline

uint256

The deadline before the trade expires.

Returns

Name
Type
Description

baseTokenOutputAmount

uint256

The amount of base tokens received.

fractionalTokenOutputAmount

uint256

The amount of fractional tokens received.

buy

Buys fractional tokens from the pair.

function buy(uint256 outputAmount, uint256 maxInputAmount, uint256 deadline)
    public
    payable
    returns (uint256 inputAmount);

Parameters

Name
Type
Description

outputAmount

uint256

The amount of fractional tokens to buy.

maxInputAmount

uint256

The maximum amount of base tokens to spend.

deadline

uint256

The deadline before the trade expires.

Returns

Name
Type
Description

inputAmount

uint256

The amount of base tokens spent.

sell

Sells fractional tokens to the pair.

function sell(uint256 inputAmount, uint256 minOutputAmount, uint256 deadline) public returns (uint256 outputAmount);

Parameters

Name
Type
Description

inputAmount

uint256

The amount of fractional tokens to sell.

minOutputAmount

uint256

The minimum amount of base tokens to receive.

deadline

uint256

The deadline before the trade expires.

Returns

Name
Type
Description

outputAmount

uint256

The amount of base tokens received.

wrap

Wraps NFTs into fractional tokens.

function wrap(uint256[] calldata tokenIds, bytes32[][] calldata proofs, ReservoirOracle.Message[] calldata messages)
    public
    returns (uint256 fractionalTokenAmount);

Parameters

Name
Type
Description

tokenIds

uint256[]

The ids of the NFTs to wrap.

proofs

bytes32[][]

The merkle proofs for the NFTs proving that they can be used in the pair.

messages

Message.ReservoirOracle[]

Returns

Name
Type
Description

fractionalTokenAmount

uint256

The amount of fractional tokens minted.

unwrap

Unwraps fractional tokens into NFTs.

function unwrap(uint256[] calldata tokenIds, bool withFee) public returns (uint256 fractionalTokenAmount);

Parameters

Name
Type
Description

tokenIds

uint256[]

The ids of the NFTs to unwrap.

withFee

bool

Whether to pay a fee for unwrapping or not.

Returns

Name
Type
Description

fractionalTokenAmount

uint256

The amount of fractional tokens burned.

nftAdd

nftAdd Adds liquidity to the pair using NFTs.

function nftAdd(
    uint256 baseTokenAmount,
    uint256[] calldata tokenIds,
    uint256 minLpTokenAmount,
    uint256 minPrice,
    uint256 maxPrice,
    uint256 deadline,
    bytes32[][] calldata proofs,
    ReservoirOracle.Message[] calldata messages
) public payable returns (uint256 lpTokenAmount);

Parameters

Name
Type
Description

baseTokenAmount

uint256

The amount of base tokens to add.

tokenIds

uint256[]

The ids of the NFTs to add.

minLpTokenAmount

uint256

The minimum amount of lp tokens to receive.

minPrice

uint256

The minimum price of the pair.

maxPrice

uint256

The maximum price of the pair.

deadline

uint256

The deadline for the transaction.

proofs

bytes32[][]

The merkle proofs for the NFTs.

messages

Message.ReservoirOracle[]

Returns

Name
Type
Description

lpTokenAmount

uint256

The amount of lp tokens minted.

nftRemove

Removes liquidity from the pair using NFTs.

function nftRemove(
    uint256 lpTokenAmount,
    uint256 minBaseTokenOutputAmount,
    uint256 deadline,
    uint256[] calldata tokenIds,
    bool withFee
) public returns (uint256 baseTokenOutputAmount, uint256 fractionalTokenOutputAmount);

Parameters

Name
Type
Description

lpTokenAmount

uint256

The amount of lp tokens to remove.

minBaseTokenOutputAmount

uint256

The minimum amount of base tokens to receive.

deadline

uint256

The deadline before the trade expires.

tokenIds

uint256[]

The ids of the NFTs to remove.

withFee

bool

Whether to pay a fee for unwrapping or not.

Returns

Name
Type
Description

baseTokenOutputAmount

uint256

The amount of base tokens received.

fractionalTokenOutputAmount

uint256

The amount of fractional tokens received.

nftBuy

Buys NFTs from the pair using base tokens.

function nftBuy(uint256[] calldata tokenIds, uint256 maxInputAmount, uint256 deadline)
    public
    payable
    returns (uint256 inputAmount);

Parameters

Name
Type
Description

tokenIds

uint256[]

The ids of the NFTs to buy.

maxInputAmount

uint256

The maximum amount of base tokens to spend.

deadline

uint256

The deadline before the trade expires.

Returns

Name
Type
Description

inputAmount

uint256

The amount of base tokens spent.

nftSell

Sells NFTs to the pair for base tokens.

function nftSell(
    uint256[] calldata tokenIds,
    uint256 minOutputAmount,
    uint256 deadline,
    bytes32[][] calldata proofs,
    ReservoirOracle.Message[] calldata messages
) public returns (uint256 outputAmount);

Parameters

Name
Type
Description

tokenIds

uint256[]

The ids of the NFTs to sell.

minOutputAmount

uint256

The minimum amount of base tokens to receive.

deadline

uint256

The deadline before the trade expires.

proofs

bytes32[][]

The merkle proofs for the NFTs.

messages

Message.ReservoirOracle[]

Returns

Name
Type
Description

outputAmount

uint256

The amount of base tokens received.

close

Closes the pair to new wraps.

Can only be called by the caviar owner. This is used as an emergency exit in case the caviar owner suspects that the pair has been compromised.

function close() public;

withdraw

Withdraws a particular NFT from the pair.

Can only be called by the caviar owner after the close grace period has passed. This is used to auction off the NFTs in the pair in case NFTs get stuck due to liquidity imbalances. Proceeds from the auction should be distributed pro rata to fractional token holders. See documentation for more details.

function withdraw(uint256 tokenId) public;

baseTokenReserves

function baseTokenReserves() public view returns (uint256);

fractionalTokenReserves

function fractionalTokenReserves() public view returns (uint256);

price

The current price of one fractional token in base tokens with 18 decimals of precision.

Calculated by dividing the base token reserves by the fractional token reserves.

function price() public view returns (uint256);

Returns

Name
Type
Description

<none>

uint256

price The price of one fractional token in base tokens * 1e18.

buyQuote

The amount of base tokens required to buy a given amount of fractional tokens.

Calculated using the xyk invariant and a 30bps fee.

function buyQuote(uint256 outputAmount) public view returns (uint256);

Parameters

Name
Type
Description

outputAmount

uint256

The amount of fractional tokens to buy.

Returns

Name
Type
Description

<none>

uint256

inputAmount The amount of base tokens required.

sellQuote

The amount of base tokens received for selling a given amount of fractional tokens.

Calculated using the xyk invariant and a 30bps fee.

function sellQuote(uint256 inputAmount) public view returns (uint256);

Parameters

Name
Type
Description

inputAmount

uint256

The amount of fractional tokens to sell.

Returns

Name
Type
Description

<none>

uint256

outputAmount The amount of base tokens received.

addQuote

The amount of lp tokens received for adding a given amount of base tokens and fractional tokens.

Calculated as a share of existing deposits. If there are no existing deposits, then initializes to sqrt(baseTokenAmount * fractionalTokenAmount).

function addQuote(uint256 baseTokenAmount, uint256 fractionalTokenAmount, uint256 lpTokenSupply)
    public
    view
    returns (uint256);

Parameters

Name
Type
Description

baseTokenAmount

uint256

The amount of base tokens to add.

fractionalTokenAmount

uint256

The amount of fractional tokens to add.

lpTokenSupply

uint256

Returns

Name
Type
Description

<none>

uint256

lpTokenAmount The amount of lp tokens received.

removeQuote

The amount of base tokens and fractional tokens received for burning a given amount of lp tokens.

Calculated as a share of existing deposits.

function removeQuote(uint256 lpTokenAmount) public view returns (uint256, uint256);

Parameters

Name
Type
Description

lpTokenAmount

uint256

The amount of lp tokens to burn.

Returns

Name
Type
Description

<none>

uint256

baseTokenAmount The amount of base tokens received.

<none>

uint256

fractionalTokenAmount The amount of fractional tokens received.

_transferFrom

function _transferFrom(address from, address to, uint256 amount) internal returns (bool);

_validateTokensAreNotStolen

function _validateTokensAreNotStolen(uint256[] calldata tokenIds, ReservoirOracle.Message[] calldata messages)
    internal
    view;

_validateTokenIds

Validates that the given tokenIds are valid for the contract's merkle root. Reverts if any of the tokenId proofs are invalid.

function _validateTokenIds(uint256[] calldata tokenIds, bytes32[][] calldata proofs) internal view;

_baseTokenReserves

Returns the current base token reserves. If the base token is ETH then it ignores the msg.value that is being sent in the current call context - this is to ensure the xyk math is correct in the buy() and add() functions.

function _baseTokenReserves() internal view returns (uint256);

Events

Add

event Add(uint256 indexed baseTokenAmount, uint256 indexed fractionalTokenAmount, uint256 indexed lpTokenAmount);

Remove

event Remove(uint256 indexed baseTokenAmount, uint256 indexed fractionalTokenAmount, uint256 indexed lpTokenAmount);

Buy

event Buy(uint256 indexed inputAmount, uint256 indexed outputAmount);

Sell

event Sell(uint256 indexed inputAmount, uint256 indexed outputAmount);

Wrap

event Wrap(uint256[] indexed tokenIds);

Unwrap

event Unwrap(uint256[] indexed tokenIds);

Close

event Close(uint256 indexed closeTimestamp);

Withdraw

event Withdraw(uint256 indexed tokenId);

Last updated