FlowYieldVaults is a yield farming platform built on the Flow blockchain using Cadence. The platform enables users to deposit tokens to supported DeFi strategies such as collateralized borrowing via FlowCreditMarket's Active Lending Platform. FlowYieldVaults aims to support yield-generating strategies, automatically optimizing returns through DeFi Actions components and auto-balancing mechanisms.
The FlowYieldVaults platform consists of several interconnected components:
The main contract that orchestrates the entire yield farming system:
- Strategy Interface: Defines yield-generating strategies that can deposit/withdraw tokens
- StrategyComposer: Creates and manages different strategy implementations
- StrategyFactory: Manages multiple strategy composers and creates strategy instances
- YieldVault Resource: Represents a user's position in a specific strategy
- YieldVaultManager: Manages multiple YieldVault positions for a user account
Implements specific yield strategies:
- TracerStrategy: A strategy that uses FlowCreditMarket lending positions with auto-balancing
- TracerStrategyComposer: Creates TracerStrategy instances with complex DeFi Actions stacking
- StrategyComposerIssuer: Controls access to strategy composer creation
Manages automated rebalancing of positions:
- Stores AutoBalancer instances in contract storage
- Automatically rebalances positions when they move outside configured thresholds
- Cleans up AutoBalancers when strategies are closed
Mock FungibleToken implementations representing:
- YieldToken: Receipt tokens for yield-bearing positions
- MOET: FlowCreditMarket's synthetic stablecoin
- Provides price feeds for testing and demonstrations
- Supports price manipulation for testing scenarios
- Implements DeFiActions.PriceOracle interface
- Simulates token swapping functionality
- Uses oracle prices to calculate swap rates
- Manages liquidity connectors for different token pairs
| Asset Name | Cadence Address | Cadence Contract Name | EVM |
|---|---|---|---|
| FlowActions | 0xd27920b6384e2a78 | DeFiActions | TBD |
| FlowCreditMarket | 0xd27920b6384e2a78 | FlowALP | TBD |
| FlowYieldVaults | 0xd27920b6384e2a78 | FlowYieldVaults | TBD |
| FlowYieldVaultsStrategies | 0xd27920b6384e2a78 | FlowYieldVaultsStrategies | TBD |
| MOET | 0xd27920b6384e2a78 | MOET | 0x51f5cc5f50afb81e8f23c926080fa38c3024b238 |
| USDC | 0xdfc20aee650fcbdf | EVMVMBridgedToken_d431955d55a99ef69beb96ba34718d0f9fbc91b1 | 0xd431955D55a99EF69BEb96BA34718d0f9fBc91b1 |
| wBTC | 0xdfc20aee650fcbdf | EVMVMBridgedToken_208d09d2a6dd176e3e95b3f0de172a7471c5b2d6 | 0x208d09d2a6Dd176e3e95b3F0DE172A7471C5B2d6 |
| wETH | 0xdfc20aee650fcbdf | EVMVMBridgedToken_059a77239dafa770977dd9f1e98632c3e4559848 | 0x059A77239daFa770977DD9f1E98632C3E4559848 |
| mUSDC (ERC4626) | 0xdfc20aee650fcbdf | EVMVMBridgedToken_4154d5B0E2931a0A1E5b733f19161aa7D2fc4b95 | 0x4154d5B0E2931a0A1E5b733f19161aa7D2fc4b95 |
| Asset Name | Cadence Address | Cadence Contract Name | EVM |
|---|---|---|---|
| FlowActions | 0x6d888f175c158410 | DeFiActions | TBD |
| FlowCreditMarket | 0x6b00ff876c299c61 | FlowALP | TBD |
| FlowYieldVaults | 0xb1d63873c3cc9f79 | FlowYieldVaults | TBD |
| FlowYieldVaultsStrategies | 0xb1d63873c3cc9f79 | FlowYieldVaultsStrategies | TBD |
| MOET | 0x6b00ff876c299c61 | MOET | 0x213979bB8A9A86966999b3AA797C1fcf3B967ae2 |
| USDC | 0x1e4aa0b87d10b141 | EVMVMBridgedToken_f1815bd50389c46847f0bda824ec8da914045d14 | 0xF1815bd50389c46847f0Bda824eC8da914045D14 |
| USDF | 0x1e4aa0b87d10b141 | EVMVMBridgedToken_2aabea2058b5ac2d339b163c6ab6f2b6d53aabed | 0x2aabea2058b5ac2d339b163c6ab6f2b6d53aabed |
| cbBTC | 0x1e4aa0b87d10b141 | EVMVMBridgedToken_a0197b2044d28b08be34d98b23c9312158ea9a18 | 0xA0197b2044D28b08Be34d98b23c9312158Ea9A18 |
| wETH | 0x1e4aa0b87d10b141 | EVMVMBridgedToken_2f6f07cdcf3588944bf4c42ac74ff24bf56e7590 | 0x2F6F07CDcf3588944Bf4C42aC74ff24bF56e7590 |
| tauUSDF (ERC4626) | 0x1e4aa0b87d10b141 | EVMVMBridgedToken_c52E820d2D6207D18667a97e2c6Ac22eB26E803c | 0xc52E820d2D6207D18667a97e2c6Ac22eB26E803c |
Below is an overview of the initial prototype Tracer Strategy in the broader context of FlowCreditMarket and the FlowYieldVaults platform.
The TracerStrategy demonstrates the power of DeFi Actions composition:
User Deposit (FLOW) → FlowCreditMarket Position → MOET Issuance → Swap to YieldToken → AutoBalancer
↑
YieldToken → Swap to FLOW → Recollateralize Position
- AutoBalancers monitor the value of deposits vs. current token holdings
- When balance moves outside configured thresholds (±5%), automatic rebalancing occurs
- Excess value flows into position recollateralization
- Insufficient value triggers position adjustments
The system heavily uses DeFi Actions components:
- Sinks: Accept token deposits
- Sources: Provide token withdrawals
- Swappers: Handle token conversions
- AutoBalancers: Maintain optimal position ratios
Cadence Scripts are written in Cadence and take advantage of Native Data Availability read and format any public data on the blockchain in the way the developer needs it, without relying on pre-existing view functions in the contract.
// Returns all YieldVault IDs for a given user address
access(all) fun main(address: Address): [UInt64]?// Get token balance for an account
access(all) fun main(account: Address, vaultPath: StoragePath): UFix64Cadence Transactions are written in Cadence and allow you to compose several function calls to several contracts within a single user approval.
// Setup user account for FlowYieldVaults platform
transaction setup()// Create a new yield position
transaction create_yield_vault(strategyIdentifier: String, vaultIdentifier: String, amount: UFix64)// Deposit additional funds to existing YieldVault
transaction deposit_to_yield_vault(id: UInt64, amount: UFix64)
// Withdraw funds from a YieldVault
transaction withdraw_from_yield_vault(id: UInt64, amount: UFix64)
// Close a YieldVault and withdraw all funds
transaction close_yield_vault(id: UInt64)The local/setup_emulator.sh script provides emulator configuration for local development and testing.
flow.json contains network configurations and contract deployment settings. It is created and managed with the Flow CLI.
The FlowYieldVaults platform implements sophisticated automatic rebalancing and recollateralizing mechanisms to maintain healthy loan positions and optimize yield generation.
Important Distinction: The system has TWO different rebalancing mechanisms:
- AutoBalancer Rebalancing (DFB): Maintains optimal ratio between YieldToken holdings and expected deposit value
- Position Rebalancing (FlowCreditMarket): Maintains healthy collateralization ratios for lending positions
These work together but serve different purposes and can trigger independently based on market conditions.
Each TracerStrategy includes an AutoBalancer with configured thresholds:
- Lower Threshold: 0.95 (5% below target)
- Upper Threshold: 1.05 (5% above target)
The AutoBalancer continuously monitors the value ratio between:
- Current YieldToken holdings (actual balance)
- Expected value based on initial deposits (target balance)
When: Current YieldToken value > 105% historical value of deposits Cause: YieldToken price has increased OR position became over-collateralized leading to excess token holdings Action: AutoBalancer deposits excess YieldToken to the rebalanceSink, swapping to FLOW and recollateralizing the FlowCreditMarket position.
Automated Flow:
YieldToken (excess) → Swap to FLOW → Deposit to FlowCreditMarket Position (recollateralization)
Result:
- Excess value moved from YieldToken holdings back to collateral
- Position health improved through additional collateralization
- Maintained optimal balance between yield tokens and position safety
When: YieldToken value < 95% of expected value
Cause: Collateral price dropped or lending position at risk
Action: Position needs more collateral to maintain healthy loan-to-value ratio
Automated Flow:
YieldToken → Swap to FLOW → Add to Position Collateral → Reduce loan risk
Result:
- Position becomes healthier with improved collateralization ratio
- Reduced liquidation risk
- Maintained borrowing capacity
let autoBalancer = FlowYieldVaultsAutoBalancers._initNewAutoBalancer(
oracle: oracle, // Price feeds for value calculations
vaultType: yieldTokenType, // YieldToken holdings monitored
lowerThreshold: 0.95, // Trigger recollateralization at 95%
upperThreshold: 1.05, // Trigger rebalancing at 105%
rebalanceSink: positionSwapSink, // Where excess value goes
rebalanceSource: nil, // Not used in TracerStrategy
uniqueID: uniqueID // Links to specific Strategy
)The system creates a sophisticated token flow:
-
Initial Position Opening:
- User deposits FLOW → FlowCreditMarket Position
- Position issues MOET → Swaps to YieldToken
- YieldToken held in AutoBalancer
-
Rebalancing Infrastructure:
abaSwapSink: MOET → YieldToken → AutoBalancerabaSwapSource: YieldToken → MOET (from AutoBalancer)positionSwapSink: YieldToken → FLOW → Position (recollateralizing)
- Triggered when deposits/withdrawals push ratios outside thresholds
- Happens during normal Strategy operations
- No user intervention required
Transaction: transactions/flow-yield-vaults/admin/rebalance_auto_balancer_by_id.cdc
// Force rebalancing regardless of thresholds
transaction rebalance_auto_balancer_by_id(id: UInt64, force: Bool)Parameters:
id: YieldVault ID associated with the AutoBalancerforce: Whether to bypass threshold checks
Script: scripts/flow-yield-vaults/get_auto_balancer_balance_by_id.cdc
// Returns current YieldToken balance in AutoBalancer
access(all) fun main(id: UInt64): UFix64?Users can track their position status by comparing:
- AutoBalancer YieldToken balance (actual)
- Expected value based on deposits (target)
- Current price ratios from oracle
- Risk Management: Prevents liquidation by maintaining healthy collateral ratios
- Capital Efficiency: Maximizes borrowing capacity when collateral appreciates
- Yield Optimization: Continuously adjusts to market conditions
- User Experience: No manual intervention required for position maintenance
The rebalancing system leverages DeFi Actions components:
- Sinks: Route tokens into rebalancing flows
- Sources: Extract tokens for rebalancing operations
- Swappers: Convert between token types (MOET ↔ YieldToken ↔ FLOW)
- Oracle: Provides price data for value calculations
- AutoBalancer: Central coordination of rebalancing logic
This creates a fully automated yield farming system that adapts to market conditions while maintaining position safety.
The FlowCreditMarket implements a sophisticated interest rate system that governs borrowing costs and lending yields. This system is fundamental to the protocol's economics and affects all lending positions.
Interest rates are determined dynamically based on supply and demand:
- Debit Interest Rate: The rate charged on borrowed tokens
- Credit Interest Rate: The rate earned on deposited tokens
- Utilization-Based: Rates adjust based on the ratio of borrowed to supplied tokens
The protocol uses InterestCurve implementations to calculate rates:
// Simple example - in production, curves would be more sophisticated
access(all) struct SimpleInterestCurve: InterestCurve {
access(all) fun interestRate(creditBalance: UFix64, debitBalance: UFix64): UFix64 {
// Returns interest rate based on utilization ratio
// Higher utilization = higher rates
let utilizationRatio = debitBalance / creditBalance
return baseRate + (utilizationRatio * rateSlope)
}
}Interest compounds continuously using per-second calculations:
- Per-Second Rates: Yearly rates converted to per-second multipliers
- Interest Indices: Track cumulative interest over time
- Automatic Compounding: Interest accrues every second without manual updates
The protocol uses "scaled balances" for efficiency:
Scaled Balance = True Balance / Interest Index
True Balance = Scaled Balance × Interest Index
Benefits:
- No need to update every position when interest accrues
- Only update when deposits/withdrawals occur
- Interest automatically compounds through index growth
// Interest index compounds over time
newIndex = oldIndex × (perSecondRate ^ elapsedSeconds)- Earned by: Token depositors (lenders)
- Rate Calculation:
(debitIncome - insuranceReserve) / totalCreditBalance - Insurance Deduction: 0.1% of credit balance reserved for protocol security
- Distribution: Paid to all credit positions proportionally
- Paid by: Token borrowers
- Rate Determination: Set by interest curve based on utilization
- Market Driven: High demand = higher rates
- Risk Adjusted: Riskier assets typically have higher rates
Each supported token has individual interest parameters:
// When adding a new token to the pool
pool.addSupportedToken(
tokenType: Type<@FlowToken.Vault>(),
collateralFactor: 0.8, // 80% of value usable as collateral
borrowFactor: 1.0, // No additional risk adjustment
interestCurve: MyInterestCurve(), // Custom rate calculation
depositRate: 1000000.0, // Rate limiting for deposits
depositCapacityCap: 1000000.0 // Maximum deposit capacity
)- Collateral Factor: Percentage of token value that can be borrowed against
- Borrow Factor: Additional risk adjustment for debt calculations
- Interest Curve: Algorithm determining base interest rates
Interest accrual affects position health over time:
Health = Effective Collateral / Effective Debt
// As debt interest accrues:
// - Effective Debt increases
// - Position health decreases
// - May trigger rebalancing or liquidation
The rebalancing system accounts for interest:
- Interest Accrual: Debt grows, collateral may earn yield
- Health Monitoring: System checks if health falls below thresholds
- Automatic Adjustment: Rebalancing triggered to maintain target health
- Compound Effect: Interest earnings can be reinvested automatically
Total Credit Balance: 1,000,000 FLOW
Total Debit Balance: 800,000 FLOW
Utilization: 80%
// High utilization leads to:
Debit Interest Rate: 8% APY
Credit Interest Rate: 6.4% APY (after insurance deduction)
Total Credit Balance: 1,000,000 FLOW
Total Debit Balance: 200,000 FLOW
Utilization: 20%
// Low utilization leads to:
Debit Interest Rate: 2% APY
Credit Interest Rate: 0.36% APY (after insurance deduction)
- Borrow Costs: Monitor debit interest on borrowed amounts
- Earning Rates: Track credit interest on deposited collateral
- Health Impact: Watch how interest affects position health over time
- Rate Optimization: Adjust interest curves based on market conditions
- Risk Management: Monitor utilization ratios and adjust parameters
- Protocol Revenue: Track insurance reserves and protocol fees
- Reserve Fund: 0.1% of credit balance reserved for protocol security
- Liquidation Protection: Reserves help cover bad debt from liquidations
- Rate Stability: Insurance provides buffer for rate calculations
- Dynamic Rates: Automatically adjust to market conditions
- Utilization Caps: Prevent over-borrowing through rate increases
- Oracle Integration: Interest calculations use real-time price data
The interest rate system is designed to:
- Balance Supply/Demand: Higher rates when utilization is high
- Incentivize Stability: Rewards for providing liquidity during high demand
- Manage Risk: Insurance reserves and dynamic adjustments protect the protocol
- Enable Automation: Continuous compounding without manual intervention
This interest system is what enables the FlowCreditMarket to function as a sustainable lending platform while providing the foundation for complex yield farming strategies built on top.
The FlowCreditMarket implements a sophisticated loan health system that determines borrowing capacity, monitors position safety, and prevents liquidations. This system is fundamental to how the TracerStrategy calculates how much can be borrowed against a user's initial collateral position.
Before diving into the mechanics, it's important to understand the core terminology used throughout the FlowCreditMarket loan system:
- Position: A lending/borrowing account that holds collateral and debt across multiple token types
- Position ID (pid): Unique identifier for each lending position in the protocol
- Position Health: Numerical ratio representing the safety of a lending position (Effective Collateral ÷ Effective Debt)
- Balance Direction: Whether a token balance is Credit (collateral/deposit) or Debit (borrowed/debt)
- Effective Collateral: Total USD value of all collateral deposits, adjusted by their respective Collateral Factors
- Effective Debt: Total USD value of all borrowed amounts, adjusted by their respective Borrow Factors
- Oracle Price: Real-time market price of tokens provided by price oracles (e.g., FLOW = $1.00, YieldToken = $2.00)
- Token Value: Raw USD value of token amount (Token Amount × Oracle Price)
- Collateral Factor: Percentage (0.0-1.0) of a token's value that counts toward borrowing capacity (e.g., 0.8 = 80%)
- Borrow Factor: Risk adjustment (0.0-1.0) applied to borrowed amounts for additional safety margins
- Target Health: Optimal health ratio (default: 1.3) that the protocol maintains through automatic rebalancing
- Minimum Health: Liquidation threshold (default: 1.1) below which positions become unsafe
- Maximum Health: Upper bound that triggers automatic draw-down of excess collateral
- Scaled Balance: Stored balance amount that doesn't change with interest accrual
- True Balance: Actual current balance including accumulated interest (Scaled Balance × Interest Index)
- Interest Index: Compound multiplier that tracks accumulated interest over time
- Token State: Global state tracking interest rates, indices, and lending parameters for each token type
- Liquidation: Forced closure of unhealthy positions to protect the protocol and lenders
- Rebalancing: Automatic adjustment of positions to maintain target health ratios
- Top-Up Source: Optional funding source that can add collateral to prevent liquidation
- Draw-Down Sink: Destination for excess funds when positions become over-collateralized
The protocol calculates position health using the formula:
Position Health = Effective Collateral / Effective Debt
// From FlowCreditMarket.cdc
access(all) fun healthComputation(effectiveCollateral: UFix64, effectiveDebt: UFix64): UFix64 {
if effectiveCollateral == 0.0 {
return 0.0
} else if effectiveDebt == 0.0 {
return UFix64.max // Infinite health - no debt
} else {
return effectiveCollateral / effectiveDebt
}
}For each token type in a position:
Token Value = Token Amount × Oracle Price
Effective Collateral += Token Value × Collateral Factor
For each borrowed token type:
Token Value = Token Amount × Oracle Price
Effective Debt += Token Value ÷ Borrow Factor
- Definition: Percentage of token value that can be used as collateral
- Range: 0.0 to 1.0 (0% to 100%)
- Purpose: Manages risk based on token volatility and liquidity
- Example: FLOW with 0.8 collateral factor means 80% of FLOW value counts toward borrowing capacity
- Definition: Risk adjustment applied to borrowed amounts
- Range: 0.0 to 1.0 (0% to 100%)
- Purpose: Additional safety margin for high-risk borrowing scenarios
- Effect: Lower borrow factor = higher effective debt for same borrowed amount
- Default Value: 1.3 (130% collateralization)
- Purpose: Optimal health level the protocol maintains through rebalancing
- Getter:
getTargetHealth() - Setter:
setTargetHealth(targetHealth: UFix64)(governance only)
- Default Value: 1.1 (110% collateralization)
- Purpose: Liquidation threshold - positions below this health are at risk
- Getter:
getMinHealth() - Setter:
setMinHealth(minHealth: UFix64)(governance only)
- Purpose: Upper bound for automatic rebalancing
- Behavior: Positions above this trigger draw-down to target health
When a user deposits collateral, the protocol calculates maximum borrowing capacity:
// Simplified borrowing capacity calculation
let tokenValue = collateralAmount × oraclePrice
let effectiveCollateral = tokenValue × collateralFactor
let maxBorrowableValue = effectiveCollateral ÷ targetHealth
let maxBorrowableTokens = maxBorrowableValue × borrowFactor ÷ borrowTokenPrice- User deposits 100 FLOW at $1.00 each
- FLOW collateral factor: 0.8 (80%)
- Target health: 1.3 (130%)
- MOET borrow factor: 1.0 (100%)
Token Value = 100 FLOW × $1.00 = $100
Effective Collateral = $100 × 0.8 = $80
Max Borrowable Value = $80 ÷ 1.3 = $61.54
Max MOET Borrowable = $61.54 × 1.0 ÷ $1.00 = 61.54 MOET
The protocol uses scaled balances for efficient interest calculations:
// Convert scaled balance to actual balance
fun scaledBalanceToTrueBalance(scaledBalance: UFix64, interestIndex: UInt64): UFix64 {
let indexMultiplier = UFix64.fromBigEndianBytes(interestIndex.toBigEndianBytes())! / 100000000.0
return scaledBalance * indexMultiplier
}// Interest compounds continuously
newIndex = oldIndex × (perSecondRate ^ elapsedSeconds)access(all) struct BalanceSheet {
access(all) let effectiveCollateral: UFix64
access(all) let effectiveDebt: UFix64
access(all) let health: UFix64
}access(all) fun positionHealth(pid: UInt64): UFix64 {
var effectiveCollateral = 0.0
var effectiveDebt = 0.0
for type in position.balances.keys {
let balance = position.balances[type]!
let tokenState = self.tokenState(type: type)
let tokenPrice = self.priceOracle.price(ofToken: type)!
if balance.direction == BalanceDirection.Credit {
// Collateral calculation
let trueBalance = scaledBalanceToTrueBalance(
scaledBalance: balance.scaledBalance,
interestIndex: tokenState.creditInterestIndex
)
let value = tokenPrice * trueBalance
effectiveCollateral += (value * self.collateralFactor[type]!)
} else {
// Debt calculation
let trueBalance = scaledBalanceToTrueBalance(
scaledBalance: balance.scaledBalance,
interestIndex: tokenState.debitInterestIndex
)
let value = tokenPrice * trueBalance
effectiveDebt += (value / self.borrowFactor[type]!)
}
}
return healthComputation(effectiveCollateral: effectiveCollateral, effectiveDebt: effectiveDebt)
}The protocol calculates how much can be withdrawn while maintaining target health:
access(all) fun fundsAvailableAboveTargetHealth(pid: UInt64, type: Type, targetHealth: UFix64): UFix64Logic:
- Calculate current effective collateral and debt
- Determine maximum debt increase that maintains target health
- Convert to token amount using price oracle and borrow factor
Calculates additional deposits needed to reach target health:
access(all) fun fundsRequiredForTargetHealth(pid: UInt64, type: Type, targetHealth: UFix64): UFix64access(all) fun healthAfterWithdrawal(pid: UInt64, type: Type, amount: UFix64): UFix64- Returns projected health after withdrawal
- Values below 1.0 indicate withdrawal would fail
- Used to prevent unhealthy withdrawals
access(all) fun healthAfterDeposit(pid: UInt64, type: Type, amount: UFix64): UFix64- Calculates health improvement from deposits
- Accounts for debt payoff vs collateral increase
The protocol continuously monitors position health and triggers rebalancing:
// From rebalancePosition function
let balanceSheet = self.positionBalanceSheet(pid: pid)
if balanceSheet.health < position.targetHealth {
// Under-collateralized: need more collateral or debt payoff
// Trigger top-up from repayment source
} else if balanceSheet.health > position.targetHealth {
// Over-collateralized: can borrow more or withdraw excess
// Trigger draw-down to sink
}The TracerStrategy leverages this health system:
- Initial Position: Deposits FLOW, borrows MOET at target health (1.3)
- Health Monitoring: AutoBalancer tracks YieldToken value vs expected value
- Price Changes: Oracle price updates affect position health
- Automatic Rebalancing: System maintains health within target range
- Positions below
minHealth(1.1) trigger automatic intervention - System attempts to use
repaymentSourcebefore liquidation - Multiple rebalancing attempts before declaring position unhealthy
// Position structure includes automatic top-up capability
access(EImplementation) var topUpSource: {DeFiActions.Source}?// All health calculations use live oracle prices
let tokenPrice = self.priceOracle.price(ofToken: type)!
let value = tokenPrice * trueBalance- Each token type has individual collateral and borrow factors
- Oracle provides prices in terms of default token (typically FLOW)
- Health calculations aggregate across all position tokens
- Borrowing capacity increases with collateral value appreciation
- Automatic recognition of additional borrowing room
- Enables strategies to leverage favorable market conditions
- All balance calculations include accrued interest
- Compound interest affects both collateral and debt over time
- Health automatically adjusts for interest accumulation
- Single position can hold multiple collateral and debt types
- Cross-collateralization enables complex strategies
- Unified health calculation across all assets
This comprehensive loan health system enables the FlowCreditMarket to safely support leveraged yield farming strategies while maintaining strict risk management and protecting user funds from liquidation through automated rebalancing mechanisms.
This section provides a step-by-step guide to test rebalancing functionality in the mock environment by manipulating collateral prices and observing the automatic rebalancing effects.
COLLATERAL PRICE REBALANCING WITH CONTRACT INTERACTIONS
YIELD TOKEN PRICE REBALANCING WITH CONTRACT INTERACTIONS
The AutoBalancer deposits to a Sink, withdrawing YIELD from the nested Vault. The inner Sink is a SwapSink that swaps from YIELD to FLOW and then deposits to a PositionSink. The deposited FLOW makes its way to the Pool and recollateralizes the position, increasing the position's size. The protocol then pushes the surplus value to its drawDownSink. That drawDownSink is also a SwapSink that takes the deposited MOET, swaps it to YIELD and then deposits the swapped tokens to the AutoBalancerSink. That sink then finally deposits the YIELD to the AutoBalancer on which the rebalance was initially called, increasing the valueOfDeposits and closing the loop.
YIELD TOKEN DOWN Scenario not currently supported
- Set up your test environment with the Flow emulator
- Deploy all contracts including mocks
- Create a YieldVault position using
create_yield_vaulttransaction - Fund the MockSwapper with liquidity for all token pairs
Each scenario below is completely self-contained and can be run independently. You only need to ensure that contracts are already deployed to the Flow emulator. Each scenario handles its own setup, execution, and verification.
Prerequisites: Flow emulator running with all FlowYieldVaults contracts deployed.
What happens: FLOW price increases → Position becomes over-collateralized → AutoBalancer may rebalance if YieldToken holdings exceed threshold
Expected Outcome: If AutoBalancer triggers: fewer YieldTokens (sold for collateral), stronger position health
#!/bin/bash
echo "=== SCENARIO 1: FLOW PRICE INCREASE ==="
echo "Setting up independent test environment..."
# Variables for this scenario
export YOUR_ADDRESS="0xf8d6e0586b0a20c7" # Default test account
export INITIAL_DEPOSIT=100.0
# Step 1: Setup account for FlowYieldVaults platform
echo "Setting up FlowYieldVaults account..."
flow transactions send cadence/transactions/flow-yield-vaults/setup.cdc \
--signer test-account
# Step 2: Setup token vaults
echo "Setting up token vaults..."
flow transactions send cadence/transactions/moet/setup_vault.cdc \
--signer test-account
flow transactions send cadence/transactions/yield-token/setup_vault.cdc \
--signer test-account
# Step 3: Initialize token prices
echo "Setting initial token prices..."
flow transactions send cadence/transactions/mocks/oracle/set_price.cdc \
"A.0ae53cb6e3f42a79.FlowToken.Vault" \
1.0 \
--signer test-account
flow transactions send cadence/transactions/mocks/oracle/set_price.cdc \
"A.045a1763c93006ca.YieldToken.Vault" \
2.0 \
--signer test-account
flow transactions send cadence/transactions/mocks/oracle/set_price.cdc \
"A.045a1763c93006ca.MOET.Vault" \
1.0 \
--signer test-account
# Step 4: Fund MockSwapper with liquidity
echo "Funding MockSwapper with liquidity..."
flow transactions send cadence/transactions/mocks/swapper/set_liquidity_connector.cdc \
"/storage/flowTokenVault" \
--signer test-account
flow transactions send cadence/transactions/mocks/swapper/set_liquidity_connector.cdc \
"/storage/moetTokenVault_0x045a1763c93006ca" \
--signer test-account
flow transactions send cadence/transactions/mocks/swapper/set_liquidity_connector.cdc \
"/storage/yieldTokenVault_0x045a1763c93006ca" \
--signer test-account
# Step 5: Create YieldVault position
echo "Creating YieldVault position with $INITIAL_DEPOSIT FLOW..."
flow transactions send cadence/transactions/flow-yield-vaults/create_yield_vault.cdc \
"A.045a1763c93006ca.FlowYieldVaultsStrategies.TracerStrategy" \
"A.0ae53cb6e3f42a79.FlowToken.Vault" \
$INITIAL_DEPOSIT \
--signer test-account
# Step 6: Get the YieldVault ID
echo "Getting YieldVault ID..."
YIELD_VAULT_ID=$(flow scripts execute cadence/scripts/flow-yield-vaults/get_yield_vault_ids.cdc \
$YOUR_ADDRESS | grep -o '[0-9]\+' | head -1)
echo "YieldVault ID: $YIELD_VAULT_ID"
# Step 7: Record baseline metrics
echo "=== RECORDING BASELINE METRICS ==="
echo "Initial FLOW Price:"
flow scripts execute cadence/scripts/mocks/oracle/get_price.cdc \
"A.0ae53cb6e3f42a79.FlowToken.Vault"
echo "Initial YieldToken Price:"
flow scripts execute cadence/scripts/mocks/oracle/get_price.cdc \
"A.045a1763c93006ca.YieldToken.Vault"
echo "Initial YieldVault Balance:"
flow scripts execute cadence/scripts/flow-yield-vaults/get_yield_vault_balance.cdc \
$YOUR_ADDRESS $YIELD_VAULT_ID
echo "Initial AutoBalancer Balance:"
flow scripts execute cadence/scripts/flow-yield-vaults/get_auto_balancer_balance_by_id.cdc \
$YIELD_VAULT_ID
# Step 8: Execute the test - Increase FLOW price by 20%
echo "=== EXECUTING TEST: FLOW PRICE INCREASE ==="
echo "Setting FLOW price from $1.00 to $1.20 (+20%)"
flow transactions send cadence/transactions/mocks/oracle/set_price.cdc \
"A.0ae53cb6e3f42a79.FlowToken.Vault" \
1.2 \
--signer test-account
echo "Confirming new FLOW price:"
flow scripts execute cadence/scripts/mocks/oracle/get_price.cdc \
"A.0ae53cb6e3f42a79.FlowToken.Vault"
# Step 9: Trigger rebalancing
echo "Triggering rebalancing..."
flow transactions send cadence/transactions/flow-yield-vaults/admin/rebalance_auto_balancer_by_id.cdc \
$YIELD_VAULT_ID true \
--signer test-account
flow transactions send cadence/transactions/flow-credit-market/pool-management/rebalance_position.cdc \
$YIELD_VAULT_ID true \
--signer test-account
# Step 10: Verify results
echo "=== VERIFYING RESULTS ==="
echo "New AutoBalancer Balance (should be HIGHER):"
flow scripts execute cadence/scripts/flow-yield-vaults/get_auto_balancer_balance_by_id.cdc \
$YIELD_VAULT_ID
echo "New YieldVault Balance):"
flow scripts execute cadence/scripts/flow-yield-vaults/get_yield_vault_balance.cdc \
$YOUR_ADDRESS $YIELD_VAULT_ID
echo "SCENARIO 1 COMPLETE!"
echo "Expected Results:"
echo "- If AutoBalancer triggers: YieldToken balance may DECREASE (sold for collateral)"
echo "- Position health should IMPROVE from additional collateral"
echo "- FLOW price increase may trigger AutoBalancer rebalanceSink if YieldToken value exceeds threshold"What You Should See:
- Position health improves (higher FLOW collateral value)
- AutoBalancer may trigger rebalanceSink if YieldToken holdings exceed threshold
- If rebalancing occurs: YieldToken balance decreases (sold for additional collateral)
What happens: FLOW price decreases → Position becomes under-collateralized → Position may use topUpSource (AutoBalancer) to add collateral
Expected Outcome: Position health stabilized through topUpSource mechanism, may reduce YieldToken holdings
#!/bin/bash
echo "=== SCENARIO 2: FLOW PRICE DECREASE ==="
echo "Setting up independent test environment..."
# Variables for this scenario
export YOUR_ADDRESS="0xf8d6e0586b0a20c7" # Default test account
export INITIAL_DEPOSIT=100.0
# Step 1: Setup account for FlowYieldVaults platform
echo "Setting up FlowYieldVaults account..."
flow transactions send transactions/flow-yield-vaults/setup.cdc \
--signer test-account
# Step 2: Setup token vaults
echo "Setting up token vaults..."
flow transactions send transactions/moet/setup_vault.cdc \
--signer test-account
flow transactions send transactions/yield-token/setup_vault.cdc \
--signer test-account
# Step 3: Initialize token prices
echo "Setting initial token prices..."
flow transactions send transactions/mocks/oracle/set_price.cdc \
--arg String:"A.0ae53cb6e3f42a79.FlowToken.Vault" \
--arg UFix64:1.0 \
--signer test-account
flow transactions send transactions/mocks/oracle/set_price.cdc \
--arg String:"A.0ae53cb6e3f42a79.YieldToken.Vault" \
--arg UFix64:2.0 \
--signer test-account
flow transactions send transactions/mocks/oracle/set_price.cdc \
--arg String:"A.0ae53cb6e3f42a79.MOET.Vault" \
--arg UFix64:1.0 \
--signer test-account
# Step 4: Fund MockSwapper with liquidity
echo "Funding MockSwapper with liquidity..."
flow transactions send transactions/mocks/swapper/set_liquidity_connector.cdc \
--arg String:"A.0ae53cb6e3f42a79.FlowToken.Vault" \
--arg String:"A.0ae53cb6e3f42a79.MOET.Vault" \
--arg UFix64:10000.0 \
--signer test-account
flow transactions send transactions/mocks/swapper/set_liquidity_connector.cdc \
--arg String:"A.0ae53cb6e3f42a79.MOET.Vault" \
--arg String:"A.0ae53cb6e3f42a79.YieldToken.Vault" \
--arg UFix64:10000.0 \
--signer test-account
flow transactions send transactions/mocks/swapper/set_liquidity_connector.cdc \
--arg String:"A.0ae53cb6e3f42a79.YieldToken.Vault" \
--arg String:"A.0ae53cb6e3f42a79.FlowToken.Vault" \
--arg UFix64:10000.0 \
--signer test-account
# Step 5: Create YieldVault position
echo "Creating YieldVault position with $INITIAL_DEPOSIT FLOW..."
flow transactions send transactions/flow-yield-vaults/create_yield_vault.cdc \
--arg String:"tracer" \
--arg String:"A.0ae53cb6e3f42a79.FlowToken.Vault" \
--arg UFix64:$INITIAL_DEPOSIT \
--signer test-account
# Step 6: Get the YieldVault ID
echo "Getting YieldVault ID..."
YIELD_VAULT_ID=$(flow scripts execute scripts/flow-yield-vaults/get_yield_vault_ids.cdc \
--arg Address:$YOUR_ADDRESS | grep -o '[0-9]\+' | head -1)
echo "YieldVault ID: $YIELD_VAULT_ID"
# Step 7: Record baseline metrics
echo "=== RECORDING BASELINE METRICS ==="
echo "Initial FLOW Price:"
flow scripts execute scripts/mocks/oracle/get_price.cdc \
--arg String:"A.0ae53cb6e3f42a79.FlowToken.Vault"
echo "Initial YieldToken Price:"
flow scripts execute scripts/mocks/oracle/get_price.cdc \
--arg String:"A.0ae53cb6e3f42a79.YieldToken.Vault"
echo "Initial YieldVault Balance:"
flow scripts execute scripts/flow-yield-vaults/get_yield_vault_balance.cdc \
--arg Address:$YOUR_ADDRESS --arg UInt64:$YIELD_VAULT_ID
echo "Initial AutoBalancer Balance:"
flow scripts execute scripts/flow-yield-vaults/get_auto_balancer_balance_by_id.cdc \
--arg UInt64:$YIELD_VAULT_ID
# Step 8: Execute the test - Decrease FLOW price by 30%
echo "=== EXECUTING TEST: FLOW PRICE DECREASE ==="
echo "Setting FLOW price from $1.00 to $0.70 (-30%)"
flow transactions send transactions/mocks/oracle/set_price.cdc \
--arg String:"A.0ae53cb6e3f42a79.FlowToken.Vault" \
--arg UFix64:0.7 \
--signer test-account
echo "Confirming new FLOW price:"
flow scripts execute scripts/mocks/oracle/get_price.cdc \
--arg String:"A.0ae53cb6e3f42a79.FlowToken.Vault"
# Step 9: Trigger rebalancing
echo "Triggering recollateralization..."
flow transactions send transactions/flow-yield-vaults/admin/rebalance_auto_balancer_by_id.cdc \
--arg UInt64:$YIELD_VAULT_ID \
--arg Bool:true \
--signer test-account
# Step 10: Verify results
echo "=== VERIFYING RESULTS ==="
echo "New AutoBalancer Balance (should be LOWER):"
flow scripts execute scripts/flow-yield-vaults/get_auto_balancer_balance_by_id.cdc \
--arg UInt64:$YIELD_VAULT_ID
echo "New YieldVault Balance (may be lower due to collateral needs):"
flow scripts execute scripts/flow-yield-vaults/get_yield_vault_balance.cdc \
--arg Address:$YOUR_ADDRESS --arg UInt64:$YIELD_VAULT_ID
echo "SCENARIO 2 COMPLETE!"
echo "Expected Results:"
echo "- Position may use topUpSource to add collateral (if configured)"
echo "- AutoBalancer balance may DECREASE if used as topUpSource"
echo "- Position health stabilized through topUpSource mechanism"What You Should See:
- Position health at risk (lower FLOW collateral value)
- May trigger topUpSource mechanism (AutoBalancer provides collateral if configured)
- AutoBalancer balance may decrease if used as topUpSource for position health
What happens: YieldToken price increases → AutoBalancer portfolio over-valued → Sells excess YieldTokens → Moves gains to position collateral
Expected Outcome: Gains captured and transferred to collateral, AutoBalancer rebalanced, stronger position health
#!/bin/bash
echo "=== SCENARIO 3: YIELD TOKEN PRICE INCREASE ==="
echo "Setting up independent test environment..."
# Variables for this scenario
export YOUR_ADDRESS="0xf8d6e0586b0a20c7" # Default test account
export INITIAL_DEPOSIT=100.0
# Step 1: Setup account for FlowYieldVaults platform
echo "Setting up FlowYieldVaults account..."
flow transactions send transactions/flow-yield-vaults/setup.cdc \
--signer test-account
# Step 2: Setup token vaults
echo "Setting up token vaults..."
flow transactions send transactions/moet/setup_vault.cdc \
--signer test-account
flow transactions send transactions/yield-token/setup_vault.cdc \
--signer test-account
# Step 3: Initialize token prices
echo "Setting initial token prices..."
flow transactions send transactions/mocks/oracle/set_price.cdc \
--arg String:"A.0ae53cb6e3f42a79.FlowToken.Vault" \
--arg UFix64:1.0 \
--signer test-account
flow transactions send transactions/mocks/oracle/set_price.cdc \
--arg String:"A.0ae53cb6e3f42a79.YieldToken.Vault" \
--arg UFix64:2.0 \
--signer test-account
flow transactions send transactions/mocks/oracle/set_price.cdc \
--arg String:"A.0ae53cb6e3f42a79.MOET.Vault" \
--arg UFix64:1.0 \
--signer test-account
# Step 4: Fund MockSwapper with liquidity
echo "Funding MockSwapper with liquidity..."
flow transactions send transactions/mocks/swapper/set_liquidity_connector.cdc \
--arg String:"A.0ae53cb6e3f42a79.FlowToken.Vault" \
--arg String:"A.0ae53cb6e3f42a79.MOET.Vault" \
--arg UFix64:10000.0 \
--signer test-account
flow transactions send transactions/mocks/swapper/set_liquidity_connector.cdc \
--arg String:"A.0ae53cb6e3f42a79.MOET.Vault" \
--arg String:"A.0ae53cb6e3f42a79.YieldToken.Vault" \
--arg UFix64:10000.0 \
--signer test-account
flow transactions send transactions/mocks/swapper/set_liquidity_connector.cdc \
--arg String:"A.0ae53cb6e3f42a79.YieldToken.Vault" \
--arg String:"A.0ae53cb6e3f42a79.FlowToken.Vault" \
--arg UFix64:10000.0 \
--signer test-account
# Step 5: Create YieldVault position
echo "Creating YieldVault position with $INITIAL_DEPOSIT FLOW..."
flow transactions send transactions/flow-yield-vaults/create_yield_vault.cdc \
--arg String:"tracer" \
--arg String:"A.0ae53cb6e3f42a79.FlowToken.Vault" \
--arg UFix64:$INITIAL_DEPOSIT \
--signer test-account
# Step 6: Get the YieldVault ID
echo "Getting YieldVault ID..."
YIELD_VAULT_ID=$(flow scripts execute scripts/flow-yield-vaults/get_yield_vault_ids.cdc \
--arg Address:$YOUR_ADDRESS | grep -o '[0-9]\+' | head -1)
echo "YieldVault ID: $YIELD_VAULT_ID"
# Step 7: Record baseline metrics
echo "=== RECORDING BASELINE METRICS ==="
echo "Initial FLOW Price:"
flow scripts execute scripts/mocks/oracle/get_price.cdc \
--arg String:"A.0ae53cb6e3f42a79.FlowToken.Vault"
echo "Initial YieldToken Price:"
flow scripts execute scripts/mocks/oracle/get_price.cdc \
--arg String:"A.0ae53cb6e3f42a79.YieldToken.Vault"
echo "Initial YieldVault Balance:"
flow scripts execute scripts/flow-yield-vaults/get_yield_vault_balance.cdc \
--arg Address:$YOUR_ADDRESS --arg UInt64:$YIELD_VAULT_ID
echo "Initial AutoBalancer Balance:"
flow scripts execute scripts/flow-yield-vaults/get_auto_balancer_balance_by_id.cdc \
--arg UInt64:$YIELD_VAULT_ID
# Step 8: Execute the test - Increase YieldToken price by 15%
echo "=== EXECUTING TEST: YIELD TOKEN PRICE INCREASE ==="
echo "Setting YieldToken price from $2.00 to $2.30 (+15%)"
flow transactions send transactions/mocks/oracle/set_price.cdc \
--arg String:"A.0ae53cb6e3f42a79.YieldToken.Vault" \
--arg UFix64:2.30 \
--signer test-account
echo "Confirming new YieldToken price:"
flow scripts execute scripts/mocks/oracle/get_price.cdc \
--arg String:"A.0ae53cb6e3f42a79.YieldToken.Vault"
# Step 9: Trigger rebalancing
echo "Triggering gain capture..."
flow transactions send transactions/flow-yield-vaults/admin/rebalance_auto_balancer_by_id.cdc \
--arg UInt64:$YIELD_VAULT_ID \
--arg Bool:true \
--signer test-account
# Step 10: Verify results
echo "=== VERIFYING RESULTS ==="
echo "Current YieldToken Price:"
flow scripts execute scripts/mocks/oracle/get_price.cdc \
--arg String:"A.0ae53cb6e3f42a79.YieldToken.Vault"
echo "New AutoBalancer Balance:"
flow scripts execute scripts/flow-yield-vaults/get_auto_balancer_balance_by_id.cdc \
--arg UInt64:$YIELD_VAULT_ID
echo "New YieldVault Balance (should be HIGHER from captured gains):"
flow scripts execute scripts/flow-yield-vaults/get_yield_vault_balance.cdc \
--arg Address:$YOUR_ADDRESS --arg UInt64:$YIELD_VAULT_ID
echo "SCENARIO 3 COMPLETE!"
echo "Expected Results:"
echo "- AutoBalancer should trigger rebalanceSink (excess YieldTokens sold)"
echo "- Gains captured and transferred to position as collateral"
echo "- AutoBalancer rebalanced to target ratio"What You Should See:
- AutoBalancer triggers rebalanceSink (YieldToken value exceeds threshold)
- YieldToken balance decreases (excess tokens sold at higher price)
- Position strengthened with gains transferred to collateral
What happens: YieldToken price decreases → AutoBalancer portfolio under-valued → NO automatic rebalancing (rebalanceSource = nil)
Expected Outcome: AutoBalancer cannot self-correct, manual intervention or position-level rebalancing may be needed
#!/bin/bash
echo "=== SCENARIO 4: YIELD TOKEN PRICE DECREASE ==="
echo "Setting up independent test environment..."
# Variables for this scenario
export YOUR_ADDRESS="0xf8d6e0586b0a20c7" # Default test account
export INITIAL_DEPOSIT=100.0
# Step 1: Setup account for FlowYieldVaults platform
echo "Setting up FlowYieldVaults account..."
flow transactions send transactions/flow-yield-vaults/setup.cdc \
--signer test-account
# Step 2: Setup token vaults
echo "Setting up token vaults..."
flow transactions send transactions/moet/setup_vault.cdc \
--signer test-account
flow transactions send transactions/yield-token/setup_vault.cdc \
--signer test-account
# Step 3: Initialize token prices
echo "Setting initial token prices..."
flow transactions send transactions/mocks/oracle/set_price.cdc \
--arg String:"A.0ae53cb6e3f42a79.FlowToken.Vault" \
--arg UFix64:1.0 \
--signer test-account
flow transactions send transactions/mocks/oracle/set_price.cdc \
--arg String:"A.0ae53cb6e3f42a79.YieldToken.Vault" \
--arg UFix64:2.0 \
--signer test-account
flow transactions send transactions/mocks/oracle/set_price.cdc \
--arg String:"A.0ae53cb6e3f42a79.MOET.Vault" \
--arg UFix64:1.0 \
--signer test-account
# Step 4: Fund MockSwapper with liquidity
echo "Funding MockSwapper with liquidity..."
flow transactions send transactions/mocks/swapper/set_liquidity_connector.cdc \
--arg String:"A.0ae53cb6e3f42a79.FlowToken.Vault" \
--arg String:"A.0ae53cb6e3f42a79.MOET.Vault" \
--arg UFix64:10000.0 \
--signer test-account
flow transactions send transactions/mocks/swapper/set_liquidity_connector.cdc \
--arg String:"A.0ae53cb6e3f42a79.MOET.Vault" \
--arg String:"A.0ae53cb6e3f42a79.YieldToken.Vault" \
--arg UFix64:10000.0 \
--signer test-account
flow transactions send transactions/mocks/swapper/set_liquidity_connector.cdc \
--arg String:"A.0ae53cb6e3f42a79.YieldToken.Vault" \
--arg String:"A.0ae53cb6e3f42a79.FlowToken.Vault" \
--arg UFix64:10000.0 \
--signer test-account
# Step 5: Create YieldVault position
echo "Creating YieldVault position with $INITIAL_DEPOSIT FLOW..."
flow transactions send transactions/flow-yield-vaults/create_yield_vault.cdc \
--arg String:"tracer" \
--arg String:"A.0ae53cb6e3f42a79.FlowToken.Vault" \
--arg UFix64:$INITIAL_DEPOSIT \
--signer test-account
# Step 6: Get the YieldVault ID
echo "Getting YieldVault ID..."
YIELD_VAULT_ID=$(flow scripts execute scripts/flow-yield-vaults/get_yield_vault_ids.cdc \
--arg Address:$YOUR_ADDRESS | grep -o '[0-9]\+' | head -1)
echo "YieldVault ID: $YIELD_VAULT_ID"
# Step 7: Record baseline metrics
echo "=== RECORDING BASELINE METRICS ==="
echo "Initial FLOW Price:"
flow scripts execute scripts/mocks/oracle/get_price.cdc \
--arg String:"A.0ae53cb6e3f42a79.FlowToken.Vault"
echo "Initial YieldToken Price:"
flow scripts execute scripts/mocks/oracle/get_price.cdc \
--arg String:"A.0ae53cb6e3f42a79.YieldToken.Vault"
echo "Initial YieldVault Balance:"
flow scripts execute scripts/flow-yield-vaults/get_yield_vault_balance.cdc \
--arg Address:$YOUR_ADDRESS --arg UInt64:$YIELD_VAULT_ID
echo "Initial AutoBalancer Balance:"
flow scripts execute scripts/flow-yield-vaults/get_auto_balancer_balance_by_id.cdc \
--arg UInt64:$YIELD_VAULT_ID
# Step 8: Execute the test - Decrease YieldToken price by 15%
echo "=== EXECUTING TEST: YIELD TOKEN PRICE DECREASE ==="
echo "Setting YieldToken price from $2.00 to $1.70 (-15%)"
flow transactions send transactions/mocks/oracle/set_price.cdc \
--arg String:"A.0ae53cb6e3f42a79.YieldToken.Vault" \
--arg UFix64:1.70 \
--signer test-account
echo "Confirming new YieldToken price:"
flow scripts execute scripts/mocks/oracle/get_price.cdc \
--arg String:"A.0ae53cb6e3f42a79.YieldToken.Vault"
# Step 9: Trigger rebalancing
echo "Triggering portfolio restoration..."
flow transactions send transactions/flow-yield-vaults/admin/rebalance_auto_balancer_by_id.cdc \
--arg UInt64:$YIELD_VAULT_ID \
--arg Bool:true \
--signer test-account
# Step 10: Verify results
echo "=== VERIFYING RESULTS ==="
echo "Current YieldToken Price:"
flow scripts execute scripts/mocks/oracle/get_price.cdc \
--arg String:"A.0ae53cb6e3f42a79.YieldToken.Vault"
echo "New AutoBalancer Balance (should be HIGHER in token count):"
flow scripts execute scripts/flow-yield-vaults/get_auto_balancer_balance_by_id.cdc \
--arg UInt64:$YIELD_VAULT_ID
echo "New YieldVault Balance:"
flow scripts execute scripts/flow-yield-vaults/get_yield_vault_balance.cdc \
--arg Address:$YOUR_ADDRESS --arg UInt64:$YIELD_VAULT_ID
echo "SCENARIO 4 COMPLETE!"
echo "Expected Results:"
echo "- AutoBalancer CANNOT rebalance automatically (no rebalanceSource)"
echo "- Portfolio remains under-valued"
echo "- Manual intervention or position-level rebalancing may be needed"What You Should See:
- AutoBalancer CANNOT rebalance (no rebalanceSource configured)
- YieldToken balance unchanged (no automatic top-up mechanism)
- Portfolio remains under-valued (manual intervention may be needed)
- Each scenario is completely independent - run any scenario without running others first
- Only prerequisite is deployed contracts - each scenario handles its own setup
- The
force: trueparameter bypasses threshold checks for testing - Position ID ≠ YieldVault ID - they are different identifiers in the system
- Compare baseline vs final values each scenario records and displays
- Each scenario demonstrates different market conditions the protocol handles automatically
- Scripts are copy-paste ready - save any scenario as a .sh file and execute independently
# Current YieldToken holdings in AutoBalancer
scripts/flow-yield-vaults/get_auto_balancer_balance_by_id.cdc
# Compare against expected value based on deposits
# Ratio should stay between 0.95 - 1.05 for healthy positions# Overall position health (collateralization ratio)
scripts/flow-credit-market/position_health.cdc
# Available balance for withdrawal from position
scripts/flow-credit-market/get_available_balance.cdc# Total FLOW available for withdrawal from YieldVault
scripts/flow-yield-vaults/get_yield_vault_balance.cdc
# Your account token balances
scripts/tokens/get_balance.cdc- Price increase → More borrowing capacity
- AutoBalancer YieldToken balance increases
- More MOET borrowed and converted to YieldTokens
- User's withdrawable balance increases
- Price decrease → Position at risk
- AutoBalancer sells YieldTokens for FLOW
- Additional FLOW added as collateral to position
- Position health maintained/improved
- Automatic rebalancing only occurs when ratios exceed ±5% thresholds
- Manual rebalancing (
force: true) bypasses thresholds - No rebalancing occurs if within 0.95-1.05 range and
force: false
- "Could not borrow AutoBalancer" - Ensure YieldVault ID is correct
- "No price set for token" - Set initial prices for all tokens before testing
- "Insufficient liquidity" - Fund MockSwapper with adequate token reserves
- "Position not found" - Verify FlowCreditMarket position ID (different from YieldVault ID)
# Check if oracle has price set
flow scripts execute scripts/mocks/oracle/get_price.cdc --arg String:"TOKEN_TYPE"
# Check your YieldVault IDs
flow scripts execute scripts/flow-yield-vaults/get_yield_vault_ids.cdc --arg Address:0xYourAddress
# Check supported strategies
flow scripts execute scripts/flow-yield-vaults/get_supported_strategies.cdcThis testing framework allows you to validate that the rebalancing system correctly responds to market conditions while maintaining position safety and optimizing yield generation.
- Strategies are built by composing DeFi Actions
- Each strategy can have different risk/reward profiles
- New strategies can be added by implementing the Strategy interface
- Auto-balancers continuously monitor and optimize positions
- Reduces need for manual intervention
- Maintains target risk parameters automatically
- Platform designed to support multiple token types
- Strategies can be configured for different collateral types
- Flexible vault management system
- Uses Cadence's resource model for secure asset management
- YieldVaults are resources owned by users
- Automatic cleanup when positions are closed
This is a mock implementation for development and testing purposes only. It is not intended for production use.
The contracts include extensive mock components (MockOracle, MockSwapper, etc.) that simulate real DeFi infrastructure. In a production environment, these would be replaced with actual oracle services and DEX integrations.
- Setup Account: Run the setup transaction to initialize your YieldVaultManager
- Create Strategy: Use create_yield_vault to open a yield position
- Manage Position: Deposit/withdraw funds as needed
- Monitor Performance: Use scripts to track your positions
- Close Position: Use close_yield_vault to exit and reclaim all funds
The platform provides a foundation for sophisticated yield farming strategies while maintaining the security and composability principles of the Cadence programming language.


