Creating an IAM

Creating a Vault Market

Before deploying a Royco Vault Market, there needs to already be an ERC4626 vault deployed whose deposits the IP wishes to incentivize. Royco is designed to be compatible with a wide variety of 4626 vaults, but generally the more conforming a vault is to the expected standard behavior, the more Royco functionality will be supported. If certain 4626 functions don’t comply with the 4626 standard, the ERC4626i wrapper will not function, and if certain other functions have been altered, the vault will not be able to be used as cross-margin on the Royco Orderbook, meaning an AP will be unable to farm the vault while waiting for an order on a different market to fill.

Those who wish to have a Royco Vault Market, but don’t already have a 4626 vault deployed will need to design and build one. The vault can be very expressive, but generally the action which an IP wishes to incentivize should be executed when the vault’s `deposit()` function is called, and move an amount of asset tokens equal to the `quantity` parameter passed in the function call. In order to be used in cross-margin orders,

If a non-conforming ERC4626 vault is unavoidable, a functioning 4626i wrapper, and even use in cross-margin, is still possible if the following assumptions still hold:

Necessary for a working ERC4626i wrapper and being a target market on the orderbook:

  • asset() function doesn’t revert

  • deposit() function doesn’t revert

  • convertToAssets() function doesn’t revert

  • Working previewDeposit() function with accurate return value

  • ERC20 functionality intact

Additionally necessary for using your vault for cross-margin on Royco orderbooks:

  • Withdraw function must return exactly `quantity` token to the withdrawer immediately

  • Working maxWithdraw() function with accurate return value

Always defer to checking the Royco codebase to confirm vault compatibility, especially when integrating irregular vaults.

To deploy a new ERC4626i vault, simply call ```function createIncentivizedVault(ERC4626 vault, address owner, string memory name, uint256 initialFrontendFee) public returns (ERC4626i incentivizedVault)``` on the ERC4626iFactory contract filling in the following parameters:

  • vault: the address of the vault you wish to incentivize

  • owner: the address of the IP responsible for managing rewards campaigns, setting frontend fee, etc

  • name: a descriptive name for the vault ie “Royco frxETH minting & staking vault” etc

  • initialFrontendFee: The % of incentives to be paid to the frontend when distributing incentives, must be higher than the minimum value in the factory, frontends may opt to give increased visibility, preferred treatment, etc to markets with higher fees.

Creating a Recipe Market

Royco Recipe Markets rely on the use of the Weiroll operation-chaining/scripting language. Weiroll is essentially a functional scripting language where all of the function calls are smart contract interactions. Weiroll is better than alternatives such as multicall because Weiroll allows carrying function outputs into the inputs of other function calls. This means that Weiroll can express complex compound smart contract interactions, such as swapping one token for another token, then depositing the swap output amount in some liquidity pool, without leaving any dust.

Weiroll scripts are represented as an array of bytes32 commands, so they are difficult to create by hand. Instead it is recommended to use an online builder, such as the one on Royco.com, which makes the process very simple. To create a Weiroll script without using an online builder, it is recommended to use one of the transpilers specifically designed for generating Weiroll scripts.

At the very minimum, Royco Recipe Markets require a valid Deposit script which executes the desired action in the AP’s disposable smart contract wallet. Markets should also define a Withdrawal script which calls all of the functions required to unwind an AP’s position. Markets will function without a working withdrawal script, but it will be difficult for an AP to exit their position and recover funds from their Weiroll Wallet, as the AP will have to execute the function calls needed for withdrawal manually.

Once the Weiroll script is complete, a recipe market can be created by calling ```function createMarket( address inputToken, uint256 lockupTime, uint256 frontendFee, Recipe calldata depositRecipe, Recipe calldata withdrawRecipe, RewardStyle rewardStyle) ```.

  • `inputToken` should reflect the token that we want to transfer to the Weiroll Wallet for availability during script execution. For example, suppose your action is to deposit USDC in some liquidity pool. In that case, inputToken should be set to the USDC address, and anytime an order is filled, the fill quantity of USDC will be transferred from the AP to the AP’s weiroll wallet, and may be used by the script.

  • `lockupTime` is the number of seconds the weiroll wallet will be frozen, preventing an AP from withdrawing or otherwise interacting with their position until the lockup expires.

  • `frontendFee` is the % of incentives to be paid to the frontend when distributing incentives, must be higher than the minimum value in the orderbook, frontends may opt to give increased visibility, preferred treatment, etc to markets with higher fees.

  • `depositRecipe` and `withdrawRecipe` are the Weiroll scripts generated prior to market creation

  • `rewardStyle` is an enum that determines how and when the incentives are paid to the AP, its enumerated values are as follows: 0. Upfront: pay the reward upfront when the order is filled and the action is executed. 1. Arrear: Allow the reward to be claimed via the RecipeOrderbook’s `claim()` function after the lockup has expired. 2. Forfeitable: Reward can be claimed after the lockup has expired, but may also be forfeited completely in exchange for allowing an AP to end their lockup period early.

Last updated