for (uint256 i = 0; i < assets.length; i++) { IERC20(assets[i]).approve(address(folio), amounts[i]);}
You can also use permit() for gasless approvals if tokens support ERC-2612.
4
Execute Mint
uint256 minSharesOut = 99e18; // Minimum shares after fees (slippage protection)(address[] memory returnedAssets, uint256[] memory returnedAmounts) = folio.mint( desiredShares, msg.sender, // Recipient of shares minSharesOut // Revert if you receive less than this);// You now have shares in your walletuint256 yourBalance = folio.balanceOf(msg.sender);
After minting:
Your share balance increased
Your token balances decreased by returnedAmounts
Pending fee shares increased (distributed later)
5
Set Slippage Protection (Optional)
Use allowances to limit token spend in case of state changes:
// Set minimum acceptable amounts (99% of expected)uint256[] memory minAmountsOut = new uint256[](assets.length);for (uint256 i = 0; i < assets.length; i++) { minAmountsOut[i] = amounts[i] * 99 / 100;}
3
Execute Redemption
uint256[] memory actualAmounts = folio.redeem( sharesToRedeem, msg.sender, // Recipient of assets assets, // Must match basket exactly minAmountsOut // Minimum amounts to receive);// You now have assets in your wallet// Shares were burned from your balance
The assets parameter must match the current basket exactly (same order, same tokens). Otherwise, the transaction will revert.
uint256 mintFee = folio.mintFee(); // D18{1} e.g., 0.01e18 = 1%// On a 100 share mint with 1% fee:// - User receives: ~99 shares// - Fees: ~1 share (split between DAO and fee recipients)
Characteristics:
One-time charge when minting
Does NOT cause supply inflation (taken from minted shares)
During rebalances, the basket composition may change:
// Check if a rebalance is active(, , , , IFolio.RebalanceTimestamps memory timestamps, ) = folio.getRebalance();if (block.timestamp < timestamps.availableUntil) { // Rebalance active - basket may change // Consider waiting or using larger slippage}
Folio Deprecation
Deprecated Folios can only be redeemed:
if (folio.isDeprecated()) { // Minting is disabled // Auctions are disabled // Only redemption is available folio.redeem(...);}
Zero Balance Assets
Basket tokens with zero balance are still part of the basket:
(address[] memory assets, uint256[] memory amounts) = folio.totalAssets();// Some amounts[i] may be 0// Still required to approve these tokens for minting// But actual transfer amount will be 0
Fee Accrual Timing
TVL fees accrue in full days only:
uint256 lastPoke = folio.lastPoke();uint256 nextAccrual = ((lastPoke / 1 days) + 1) * 1 days;// Fees will next accrue at nextAccrual timestamp