Contract Interfaces
A high level description of key contract functions
The Collateral contract stores collateral balances for { user, product } pairs. There is a single Collateral contract in the protocol.
Deposit pulls collateral (DSU) from the
msg.sender
and credits the product's collateral balance for the specified account.function depositTo(address account, address product, uint256 amount) external
account
- The address of the user accountproduct
- The address of the Perennial productamount
- Amount of DSU to deposit
Withdraw decrements the balance of
msg.sender
product collateral balance and pushes the DSU to the specified receiver.function withdrawTo(address receiver, address product, uint256 amount) external
account
- The address of the user accountproduct
- The address of the Perennial productamount
- Amount of DSU to deposit
Liquidate closes
account
's position for the specified product. Liquidate will revert if the user is not eligible for liquidation. function liquidate(address account, address product) external
To check if a user is liquidateable, call
function liquidatable(address account, address product) external
account
- The address of the user accountproduct
- The address of the Perennial product
The Product contract is a market in the Perennial protocol. A new product contract is deployed for each launched market via the Controller's
createProduct
method.Maker positions provide liquidity for a given product. The maximum size of a maker position is determined by the account's collateral and the product's maintenance requirement.
function openMake(uint256 amount) external
function closeMake(uint256 amount) external
amount
- Size of the maker position to open or close
Taker positions are traders in the system. The maximum size of a taker position is determined by the account's collateral, the product's maintenance requirement, and the product's liquidity (open maker positons)
function openTake(uint256 amount) external
function closeTake(uint256 amount) external
amount
- Size of the taker position to open or close
The Lens contract provides convenience functions for reading Protocol, Product, and Accounts state. The functions on the Lens contracts are designed to be called via Ether's
callStatic
method (or similar, depending on your Web3 library of choice). You can find the lens address for each deployed chain in Deployed ContractsSnapshot functions return batched data for the Protocol, and one or more Products or Accounts. For struct fields, refer to the Lens interface.
function snapshot() external returns (ProtocolSnapshot memory)
function snapshot(address product) external returns (ProductSnapshot memory)
function snapshot(address account, address product) external returns (UserProductSnapshot memory)
function snapshots(address[] calldata productAddresses) external returns (ProductSnapshot[] memory)
function snapshots(address account, address[] calldata productAddresses) external returns (UserProductSnapshot[] memory)
account
- The address of the user accountproduct
- The address of the Perennial product
The MultiInvoker allows for multiple interactions with the Perennial protocol in a single transaction.
The entrypoint to MultiInvoker is
invoke
. Each invocation can take one or multiple Actions, and will perform each action in order. For common chains, see our integration tests.function invoke(Invocation[] calldata invocations) external;
Where each
Invocation
has an action
and args
field. The args
are ABI encoded arguments, you can use the following typescript snippet to generate payloads for each action.enum InvokerAction {
NOOP,
DEPOSIT,
WITHDRAW,
OPEN_TAKE,
CLOSE_TAKE,
OPEN_MAKE,
CLOSE_MAKE,
CLAIM,
WRAP,
UNWRAP,
WRAP_AND_DEPOSIT,
WITHDRAW_AND_UNWRAP,
}
const buildInvokerAction = (
action: InvokerAction,
{
userAddress,
productAddress,
position,
amount,
programs,
}: {
userAddress?: string
productAddress?: string
position?: BigNumberish
amount?: BigNumberish
programs?: number[]
}
): IMultiInvoker.InvocationStruct => {
switch (action) {
case InvokerAction.DEPOSIT:
return {
action: 1,
args: utils.defaultAbiCoder.encode(['address', 'address', 'uint'], [userAddress, productAddress, amount]),
}
case InvokerAction.WITHDRAW:
return {
action: 2,
args: utils.defaultAbiCoder.encode(['address', 'address', 'uint'], [userAddress, productAddress, amount]),
}
case InvokerAction.OPEN_TAKE:
return {
action: 3,
args: utils.defaultAbiCoder.encode(['address', 'uint'], [productAddress, position]),
}
case InvokerAction.CLOSE_TAKE:
return {
action: 4,
args: utils.defaultAbiCoder.encode(['address', 'uint'], [productAddress, position]),
}
case InvokerAction.OPEN_MAKE:
return {
action: 5,
args: utils.defaultAbiCoder.encode(['address', 'uint'], [productAddress, position]),
}
case InvokerAction.CLOSE_MAKE:
return {
action: 6,
args: utils.defaultAbiCoder.encode(['address', 'uint'], [productAddress, position]),
}
case InvokerAction.CLAIM:
return {
action: 7,
args: utils.defaultAbiCoder.encode(['address', 'uint[]'], [productAddress, programs]),
}
case InvokerAction.WRAP:
return {
action: 8,
args: utils.defaultAbiCoder.encode(['address', 'uint'], [userAddress, amount]),
}
case InvokerAction.UNWRAP:
return {
action: 9,
args: utils.defaultAbiCoder.encode(['address', 'uint'], [userAddress, amount]),
}
case InvokerAction.WRAP_AND_DEPOSIT:
return {
action: 10,
args: utils.defaultAbiCoder.encode(['address', 'address', 'uint'], [userAddress, productAddress, amount]),
}
case InvokerAction.WITHDRAW_AND_UNWRAP:
return {
action: 11,
args: utils.defaultAbiCoder.encode(['address', 'address', 'uint'], [userAddress, productAddress, amount]),
}
default:
return { action: 0, args: '0x' }
}
}
Last modified 4mo ago