diff --git a/README.md b/README.md index 0e4aea77..62730842 100644 --- a/README.md +++ b/README.md @@ -182,6 +182,50 @@ If one of the allocators starts setting the withdraw queue and/or supply queue t ## Getting Started +### Package installation + +```bash +npm install @morpho-org/metamorpho +``` + +```bash +yarn add @morpho-org/metamorpho +``` + +### Usage + +Bundle a supply cap raise and a reallocation to the market: + +```typescript +import { MetaMorphoAction } from "@morpho-org/metamorpho"; + +const marketParams1 = { + collateralToken: "0x...", + loanToken: "0x...", + irm: "0x...", + oracle: "0x...", + lltv: 86_0000000000000000n, +}; + +const marketParams2 = { + collateralToken: "0x...", + loanToken: marketParams1.loanToken, + irm: "0x...", + oracle: "0x...", + lltv: 96_5000000000000000n, +}; + +await metamorpho.connect(curator).multicall([ + MetaMorphoAction.acceptCap(marketParams2), + MetaMorphoAction.reallocate([ + { marketParams: marketParams1, assets: 600_000000000000000000n }, + { marketParams: marketParams2, assets: 100_000000000000000000n }, + ]), +]); +``` + +## Development + Install dependencies: `yarn` Run forge tests: `yarn test:forge` diff --git a/package.json b/package.json index 3b82f83e..40c41d8f 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@morpho-org/metamorpho", "description": "MetaMorpho multicall encoder", "license": "GPL-2.0-or-later", - "version": "1.0.0", + "version": "1.1.0", "main": "lib/index.js", "bin": "lib/cli.js", "files": [ diff --git a/pkg/MetaMorphoAction.ts b/pkg/MetaMorphoAction.ts index ce0933f2..92f1d798 100644 --- a/pkg/MetaMorphoAction.ts +++ b/pkg/MetaMorphoAction.ts @@ -2,119 +2,219 @@ import { BigNumberish } from "ethers"; import { MetaMorpho__factory } from "types"; import { MarketAllocationStruct, MarketParamsStruct } from "types/src/MetaMorpho"; -export type MetaMorphoCall = string; +const METAMORPHO_IFC = MetaMorpho__factory.createInterface(); -export class MetaMorphoAction { - private static METAMORPHO_IFC = MetaMorpho__factory.createInterface(); +export type MetaMorphoCall = string; +export namespace MetaMorphoAction { /* CONFIGURATION */ - static setCurator(newCurator: string): MetaMorphoCall { - return MetaMorphoAction.METAMORPHO_IFC.encodeFunctionData("setCurator", [newCurator]); + /** + * Encodes a call to a MetaMorpho vault to set the curator. + * @param newCurator The address of the new curator. + */ + export function setCurator(newCurator: string): MetaMorphoCall { + return METAMORPHO_IFC.encodeFunctionData("setCurator", [newCurator]); } - static setIsAllocator(newAllocator: string, newIsAllocator: boolean): MetaMorphoCall { - return MetaMorphoAction.METAMORPHO_IFC.encodeFunctionData("setIsAllocator", [newAllocator, newIsAllocator]); + /** + * Encodes a call to a MetaMorpho vault to enable or disable an allocator. + * @param newAllocator The address of the allocator. + * @param newIsAllocator Whether the allocator should be enabled or disabled. + */ + export function setIsAllocator(newAllocator: string, newIsAllocator: boolean): MetaMorphoCall { + return METAMORPHO_IFC.encodeFunctionData("setIsAllocator", [newAllocator, newIsAllocator]); } - static setFeeRecipient(newFeeRecipient: string): MetaMorphoCall { - return MetaMorphoAction.METAMORPHO_IFC.encodeFunctionData("setFeeRecipient", [newFeeRecipient]); + /** + * Encode a call to a MetaMorpho vault to set the fee recipient. + * @param newFeeRecipient The address of the new fee recipient. + */ + export function setFeeRecipient(newFeeRecipient: string): MetaMorphoCall { + return METAMORPHO_IFC.encodeFunctionData("setFeeRecipient", [newFeeRecipient]); } - static setSkimRecipient(newSkimRecipient: string): MetaMorphoCall { - return MetaMorphoAction.METAMORPHO_IFC.encodeFunctionData("setSkimRecipient", [newSkimRecipient]); + /** + * Encode a call to a MetaMorpho vault to set the skim recipient. + * @param newSkimRecipient The address of the new skim recipient. + */ + export function setSkimRecipient(newSkimRecipient: string): MetaMorphoCall { + return METAMORPHO_IFC.encodeFunctionData("setSkimRecipient", [newSkimRecipient]); } - static setFee(fee: BigNumberish): MetaMorphoCall { - return MetaMorphoAction.METAMORPHO_IFC.encodeFunctionData("setFee", [fee]); + /** + * Encode a call to a MetaMorpho vault to set the fee. + * @param fee The new fee percentage (in WAD). + */ + export function setFee(fee: BigNumberish): MetaMorphoCall { + return METAMORPHO_IFC.encodeFunctionData("setFee", [fee]); } /* TIMELOCK */ - static submitTimelock(newTimelock: BigNumberish): MetaMorphoCall { - return MetaMorphoAction.METAMORPHO_IFC.encodeFunctionData("submitTimelock", [newTimelock]); + /** + * Encodes a call to a MetaMorpho vault to submit a new timelock. + * @param newTimelock The new timelock (in seconds). + */ + export function submitTimelock(newTimelock: BigNumberish): MetaMorphoCall { + return METAMORPHO_IFC.encodeFunctionData("submitTimelock", [newTimelock]); } - static acceptTimelock(): MetaMorphoCall { - return MetaMorphoAction.METAMORPHO_IFC.encodeFunctionData("acceptTimelock"); + /** + * Encodes a call to a MetaMorpho vault to accept the pending timelock. + */ + export function acceptTimelock(): MetaMorphoCall { + return METAMORPHO_IFC.encodeFunctionData("acceptTimelock"); } - static revokePendingTimelock(): MetaMorphoCall { - return MetaMorphoAction.METAMORPHO_IFC.encodeFunctionData("revokePendingTimelock"); + /** + * Encodes a call to a MetaMorpho vault to revoke the pending timelock. + */ + export function revokePendingTimelock(): MetaMorphoCall { + return METAMORPHO_IFC.encodeFunctionData("revokePendingTimelock"); } /* SUPPLY CAP */ - static submitCap(marketParams: MarketParamsStruct, newSupplyCap: BigNumberish): MetaMorphoCall { - return MetaMorphoAction.METAMORPHO_IFC.encodeFunctionData("submitCap", [marketParams, newSupplyCap]); + /** + * Encodes a call to a MetaMorpho vault to submit a new supply cap. + * @param marketParams The market params of the market of which to submit a supply cap. + * @param newSupplyCap The new supply cap. + */ + export function submitCap(marketParams: MarketParamsStruct, newSupplyCap: BigNumberish): MetaMorphoCall { + return METAMORPHO_IFC.encodeFunctionData("submitCap", [marketParams, newSupplyCap]); } - static acceptCap(marketParams: MarketParamsStruct): MetaMorphoCall { - return MetaMorphoAction.METAMORPHO_IFC.encodeFunctionData("acceptCap", [marketParams]); + /** + * Encodes a call to a MetaMorpho vault to accept the pending supply cap. + * @param marketParams The market params of the market of which to accept the pending supply cap. + */ + export function acceptCap(marketParams: MarketParamsStruct): MetaMorphoCall { + return METAMORPHO_IFC.encodeFunctionData("acceptCap", [marketParams]); } - static revokePendingCap(id: string): MetaMorphoCall { - return MetaMorphoAction.METAMORPHO_IFC.encodeFunctionData("revokePendingCap", [id]); + /** + * Encodes a call to a MetaMorpho vault to revoke the pending supply cap. + * @param id The id of the market of which to revoke the pending supply cap. + */ + export function revokePendingCap(id: string): MetaMorphoCall { + return METAMORPHO_IFC.encodeFunctionData("revokePendingCap", [id]); } /* FORCED MARKET REMOVAL */ - static submitMarketRemoval(marketParams: MarketParamsStruct): MetaMorphoCall { - return MetaMorphoAction.METAMORPHO_IFC.encodeFunctionData("submitMarketRemoval", [marketParams]); + /** + * Encodes a call to a MetaMorpho vault to submit a market removal. + * @param marketParams The market params of the market to remove. + */ + export function submitMarketRemoval(marketParams: MarketParamsStruct): MetaMorphoCall { + return METAMORPHO_IFC.encodeFunctionData("submitMarketRemoval", [marketParams]); } - static revokePendingMarketRemoval(id: string): MetaMorphoCall { - return MetaMorphoAction.METAMORPHO_IFC.encodeFunctionData("revokePendingMarketRemoval", [id]); + /** + * Encodes a call to a MetaMorpho vault to accept the pending market removal. + * @param id The id of the market of which to accept the removal. + */ + export function revokePendingMarketRemoval(id: string): MetaMorphoCall { + return METAMORPHO_IFC.encodeFunctionData("revokePendingMarketRemoval", [id]); } /* GUARDIAN */ - static submitGuardian(newGuardian: string): MetaMorphoCall { - return MetaMorphoAction.METAMORPHO_IFC.encodeFunctionData("submitGuardian", [newGuardian]); + /** + * Encodes a call to a MetaMorpho vault to submit a new guardian. + * @param newGuardian The address of the new guardian. + */ + export function submitGuardian(newGuardian: string): MetaMorphoCall { + return METAMORPHO_IFC.encodeFunctionData("submitGuardian", [newGuardian]); } - static acceptGuardian(): MetaMorphoCall { - return MetaMorphoAction.METAMORPHO_IFC.encodeFunctionData("acceptGuardian"); + /** + * Encodes a call to a MetaMorpho vault to accept the pending guardian. + */ + export function acceptGuardian(): MetaMorphoCall { + return METAMORPHO_IFC.encodeFunctionData("acceptGuardian"); } - static revokePendingGuardian(): MetaMorphoCall { - return MetaMorphoAction.METAMORPHO_IFC.encodeFunctionData("revokePendingGuardian"); + /** + * Encodes a call to a MetaMorpho vault to revoke the pending guardian. + */ + export function revokePendingGuardian(): MetaMorphoCall { + return METAMORPHO_IFC.encodeFunctionData("revokePendingGuardian"); } /* MANAGEMENT */ - static skim(erc20: string): MetaMorphoCall { - return MetaMorphoAction.METAMORPHO_IFC.encodeFunctionData("skim", [erc20]); + /** + * Encodes a call to a MetaMorpho vault to skim ERC20 tokens. + * @param erc20 The address of the ERC20 token to skim. + */ + export function skim(erc20: string): MetaMorphoCall { + return METAMORPHO_IFC.encodeFunctionData("skim", [erc20]); } - static setSupplyQueue(supplyQueue: string[]): MetaMorphoCall { - return MetaMorphoAction.METAMORPHO_IFC.encodeFunctionData("setSupplyQueue", [supplyQueue]); + /** + * Encodes a call to a MetaMorpho vault to set the supply queue. + * @param supplyQueue The new supply queue. + */ + export function setSupplyQueue(supplyQueue: string[]): MetaMorphoCall { + return METAMORPHO_IFC.encodeFunctionData("setSupplyQueue", [supplyQueue]); } - static updateWithdrawQueue(indexes: BigNumberish[]): MetaMorphoCall { - return MetaMorphoAction.METAMORPHO_IFC.encodeFunctionData("updateWithdrawQueue", [indexes]); + /** + * Encodes a call to a MetaMorpho vault to update the withdraw queue. + * @param indexes The indexes of each market in the previous withdraw queue, in the new withdraw queue's order. + */ + export function updateWithdrawQueue(indexes: BigNumberish[]): MetaMorphoCall { + return METAMORPHO_IFC.encodeFunctionData("updateWithdrawQueue", [indexes]); } - static reallocate(allocations: MarketAllocationStruct[]): MetaMorphoCall { - return MetaMorphoAction.METAMORPHO_IFC.encodeFunctionData("reallocate", [allocations]); + /** + * Encodes a call to a MetaMorpho vault to reallocate the vault's liquidity across enabled markets. + * @param allocations The new target allocations of each market. + */ + export function reallocate(allocations: MarketAllocationStruct[]): MetaMorphoCall { + return METAMORPHO_IFC.encodeFunctionData("reallocate", [allocations]); } /* ERC4626 */ - static mint(shares: BigNumberish, receiver: string): MetaMorphoCall { - return MetaMorphoAction.METAMORPHO_IFC.encodeFunctionData("mint", [shares, receiver]); - } - - static deposit(assets: BigNumberish, receiver: string): MetaMorphoCall { - return MetaMorphoAction.METAMORPHO_IFC.encodeFunctionData("deposit", [assets, receiver]); - } - - static withdraw(assets: BigNumberish, receiver: string, owner: string): MetaMorphoCall { - return MetaMorphoAction.METAMORPHO_IFC.encodeFunctionData("withdraw", [assets, receiver, owner]); - } - - static redeem(shares: BigNumberish, receiver: string, owner: string): MetaMorphoCall { - return MetaMorphoAction.METAMORPHO_IFC.encodeFunctionData("redeem", [shares, receiver, owner]); + /** + * Encodes a call to a MetaMorpho vault to mint shares. + * @param shares The amount of shares to mint. + * @param receiver The address of the receiver of the shares. + */ + export function mint(shares: BigNumberish, receiver: string): MetaMorphoCall { + return METAMORPHO_IFC.encodeFunctionData("mint", [shares, receiver]); + } + + /** + * Encodes a call to a MetaMorpho vault to deposit assets. + * @param assets The amount of assets to deposit. + * @param receiver The address of the receiver of the shares. + */ + export function deposit(assets: BigNumberish, receiver: string): MetaMorphoCall { + return METAMORPHO_IFC.encodeFunctionData("deposit", [assets, receiver]); + } + + /** + * Encodes a call to a MetaMorpho vault to withdraw assets. + * @param assets The amount of assets to withdraw. + * @param receiver The address of the receiver of the assets. + * @param owner The address of the owner of the shares to redeem. + */ + export function withdraw(assets: BigNumberish, receiver: string, owner: string): MetaMorphoCall { + return METAMORPHO_IFC.encodeFunctionData("withdraw", [assets, receiver, owner]); + } + + /** + * Encodes a call to a MetaMorpho vault to redeem shares. + * @param shares The amount of shares to redeem. + * @param receiver The address of the receiver of the assets. + * @param owner The address of the owner of the shares to redeem. + */ + export function redeem(shares: BigNumberish, receiver: string, owner: string): MetaMorphoCall { + return METAMORPHO_IFC.encodeFunctionData("redeem", [shares, receiver, owner]); } }