diff --git a/docs/blockchain-development-tutorials/forte/fixed-point-128-bit-math.md b/docs/blockchain-development-tutorials/forte/fixed-point-128-bit-math.md index fbeaff70c7..4e6fd269b0 100644 --- a/docs/blockchain-development-tutorials/forte/fixed-point-128-bit-math.md +++ b/docs/blockchain-development-tutorials/forte/fixed-point-128-bit-math.md @@ -16,10 +16,9 @@ keywords: sidebar_label: DeFi Math Utils --- -# High-Precision Fixed-Point 128 Bit Math +# High-Precision Fixed-Point 128 Bit Math -## Overview -Dealing with decimals is a notorious issue for most developers on other chains, especially when working with decentralized finance (DeFi). Blockchains are deterministic systems and floating-point arithmetic is non-deterministic across different compilers and architectures, which is why blockchains use fixed-point arithmetic via integers (scaling numbers by a fixed factor). +Dealing with decimals is a notorious issue for most developers on other chains, especially when working with decentralized finance (DeFi). Blockchains are deterministic systems and floating-point arithmetic is non-deterministic across different compilers and architectures, which is why blockchains use fixed-point arithmetic via integers (scaling numbers by a fixed factor). The issue with this is that these fixed-point integers tend to be very imprecise when using various mathematical operations on them. The more operations you apply to these numbers, the more imprecise these numbers become. However [`DeFiActionsMathUtils`] provides a standardized library for high-precision mathematical operations in DeFi applications on Flow. The contract extends Cadence's native 8-decimal precision (`UFix64`) to 24 decimals using `UInt128` for intermediate calculations, ensuring accuracy in complex financial computations while maintaining deterministic results across the network. @@ -54,7 +53,7 @@ let output = afterFee * price // More precision lost let finalAmount = output / someRatio // Even more precision lost ``` -After three-to-four sequential operations, significant cumulative rounding errors can occur, especially when dealing with large amounts. Assuming a rounding error with eight decimals (1.234567885 rounds up to 1.23456789, causing a rounding error of 0.000000005), then after 100 operations with this error and dealing with one million dollars USDF, the protocol loses $0.5 in revenue from this lack of precision. This might not seem like a lot, but if we consider the TVL of Aave, which is around 40 billion USD, then that loss results in $20,000 USD! +After three-to-four sequential operations, significant cumulative rounding errors can occur, especially when dealing with large amounts. Assuming a rounding error with eight decimals (1.234567885 rounds up to 1.23456789, causing a rounding error of 0.000000005), then after 100 operations with this error and dealing with one million dollars USDF, the protocol loses $0.5 in revenue from this lack of precision. This might not seem like a lot, but if we consider the TVL of Aave, which is around 40 billion USD, then that loss results in $20,000 USD! ## The Solution: 24-Decimal Precision @@ -62,7 +61,7 @@ After three-to-four sequential operations, significant cumulative rounding error :::Warning -There is still some precision loss occurring, but it is much smaller than with eight decimals. +There is still some precision loss occurring, but it is much smaller than with eight decimals. ::: @@ -147,7 +146,7 @@ let protocolFee = DeFiActionsMathUtils.toUFix64RoundUp(calculatedFee) let displayValue = DeFiActionsMathUtils.toUFix64Round(calculatedValue) ``` -**RoundEven** - Select this for scenarios with many repeated calculations where you want to minimize systematic bias. Also known as "[banker's rounding]", this mode rounds ties (exactly 0.5) to the nearest even number, which statistically balances out over many operations, making it ideal for large-scale distributions or statistical calculations. +**RoundEven** - Select this for scenarios with many repeated calculations where you want to minimize systematic bias. Also known as "[banker's rounding]", this mode rounds ties (exactly 0.5) to the nearest even number, which statistically balances out over many operations, making it ideal for large-scale distributions or statistical calculations. ```cadence // For repeated operations where bias matters @@ -304,23 +303,23 @@ access(all) fun calculateSwapOutput( let reserveOut = DeFiActionsMathUtils.toUInt128(outputReserve) let fee = DeFiActionsMathUtils.toUInt128(feeBasisPoints) let basisPoints = DeFiActionsMathUtils.toUInt128(10000.0) - + // Calculate: inputWithFee = inputAmount * (10000 - fee) let feeMultiplier = DeFiActionsMathUtils.div( basisPoints - fee, basisPoints ) let inputWithFee = DeFiActionsMathUtils.mul(input, feeMultiplier) - + // Calculate: numerator = inputWithFee * outputReserve let numerator = DeFiActionsMathUtils.mul(inputWithFee, reserveOut) - + // Calculate: denominator = inputReserve + inputWithFee let denominator = reserveIn + inputWithFee - + // Calculate output: numerator / denominator let output = DeFiActionsMathUtils.div(numerator, denominator) - + // Return with conservative rounding (round down for user protection) return DeFiActionsMathUtils.toUFix64RoundDown(output) } @@ -345,19 +344,19 @@ access(all) fun calculateCompoundInterest( let n = DeFiActionsMathUtils.toUInt128(UFix64(periodsPerYear)) let t = DeFiActionsMathUtils.toUInt128(numberOfYears) let one = DeFiActionsMathUtils.toUInt128(1.0) - + // Calculate: rate per period = r / n let ratePerPeriod = DeFiActionsMathUtils.div(r, n) - + // Calculate: (1 + rate per period) let onePlusRate = one + ratePerPeriod - + // Calculate: number of periods = n * t let totalPeriods = DeFiActionsMathUtils.mul(n, t) - + // Note: For production, you'd need to implement a power function // This is simplified for demonstration - + // Calculate final amount with rounding return DeFiActionsMathUtils.toUFix64Round(finalAmount) } @@ -379,11 +378,11 @@ access(all) fun calculateProportionalShare( let rewards = DeFiActionsMathUtils.toUInt128(totalRewards) let stake = DeFiActionsMathUtils.toUInt128(userStake) let total = DeFiActionsMathUtils.toUInt128(totalStaked) - + // Calculate: (userStake / totalStaked) * totalRewards let proportion = DeFiActionsMathUtils.div(stake, total) let userReward = DeFiActionsMathUtils.mul(proportion, rewards) - + // Round down for conservative payout return DeFiActionsMathUtils.toUFix64RoundDown(userReward) } @@ -405,22 +404,22 @@ access(all) fun calculatePriceImpact( let input = DeFiActionsMathUtils.toUInt128(inputAmount) let reserveIn = DeFiActionsMathUtils.toUInt128(inputReserve) let reserveOut = DeFiActionsMathUtils.toUInt128(outputReserve) - + // Calculate initial price: outputReserve / inputReserve let initialPrice = DeFiActionsMathUtils.div(reserveOut, reserveIn) - + // Calculate new reserves after trade let newReserveIn = reserveIn + input let k = DeFiActionsMathUtils.mul(reserveIn, reserveOut) let newReserveOut = DeFiActionsMathUtils.div(k, newReserveIn) - + // Calculate final price: newOutputReserve / newInputReserve let finalPrice = DeFiActionsMathUtils.div(newReserveOut, newReserveIn) - + // Calculate impact: (initialPrice - finalPrice) / initialPrice let priceDiff = initialPrice - finalPrice let impact = DeFiActionsMathUtils.div(priceDiff, initialPrice) - + return DeFiActionsMathUtils.toUFix64Round(impact) } ``` @@ -501,7 +500,7 @@ access(all) fun swap(inputAmount: UFix64) { inputAmount > 0.0: "Amount must be positive" inputAmount <= 1000000.0: "Amount exceeds maximum" } - + let inputHP = DeFiActionsMathUtils.toUInt128(inputAmount) // ... perform calculations } @@ -533,4 +532,4 @@ The simple **convert → calculate → convert back** pattern, combined with str [banker's rounding]: https://learn.microsoft.com/en-us/openspecs/microsoft_general_purpose_programming_languages/ms-vbal/98152b5a-4d86-4acb-b875-66cb1f49433e [View the DeFiActionsMathUtils source code]: https://github.com/onflow/FlowActions/blob/main/cadence/contracts/utils/DeFiActionsMathUtils.cdc [Flow DeFi Actions Documentation]: https://developers.flow.com/blockchain-development-tutorials/forte/flow-actions -[Cadence Fixed-Point Numbers]: https://cadence-lang.org/docs/language/values-and-types/fixed-point-nums-ints \ No newline at end of file +[Cadence Fixed-Point Numbers]: https://cadence-lang.org/docs/language/values-and-types/fixed-point-nums-ints diff --git a/docs/blockchain-development-tutorials/forte/flow-actions/basic-combinations.md b/docs/blockchain-development-tutorials/forte/flow-actions/basic-combinations.md index f45e2431b0..0ab20171f3 100644 --- a/docs/blockchain-development-tutorials/forte/flow-actions/basic-combinations.md +++ b/docs/blockchain-development-tutorials/forte/flow-actions/basic-combinations.md @@ -11,16 +11,6 @@ keywords: # Composing Workflows with Flow Actions -:::warning - -We are reviewing and finalizing Flow Actions in [FLIP 339]. The specific implementation may change as a part of this process. - -We will update these tutorials, but you may need to refactor your code if the implementation changes. - -::: - -## Overview - Flow Actions are designed to be **composable**, which means you can chain them together like LEGO blocks to build complex strategies. Each primitive has a standardized interface that works consistently across all protocols and eliminates the need to learn multiple APIs. This composability allows atomic execution of multi-step workflows within single transactions, ensuring either complete success or safe failure. When developers combine these primitives, they create sophisticated decentralized finance (DeFi) strategies like automated yield farming, cross-protocol arbitrage, and portfolio rebalancing. The [5 Flow Actions Primitives] are: - **Source** → Provides tokens on demand by withdrawing from vaults or claiming rewards. Sources respect minimum balance constraints and return empty vaults gracefully when nothing is available. @@ -321,7 +311,6 @@ This advanced workflow demonstrates the power of combining VaultSource with Zapp ![vault source zapper](./imgs/vaultsource-zapper.png) - **How it works:** 1. VaultSource withdraws tokens from vault while respecting minimum balance. @@ -389,7 +378,7 @@ let autoBalancer <- FlowActions.createAutoBalancer( lowerThreshold: 0.8, upperThreshold: 1.2, source: rebalanceSource, - sink: rebalanceSink, + sink: rebalanceSink, oracle: priceOracle, uniqueID: nil ) @@ -419,9 +408,9 @@ This advanced compounding strategy maximizes yield by automatically claiming sta 5. Compound interest effect increases overall position size and future rewards. ```cadence -// Restake rewards workflow +// Restake rewards workflow let rewardsSource = IncrementFiStakingConnectors.PoolRewardsSource( - poolID: 1, + poolID: 1, staker: userAddress, vaultType: Type<@FlowToken.Vault>(), overflowSinks: {}, @@ -436,13 +425,13 @@ let zapper = IncrementFiPoolLiquidityConnectors.Zapper( ) let swapSource = SwapConnectors.SwapSource( - swapper: zapper, - source: rewardsSource, + swapper: zapper, + source: rewardsSource, uniqueID: nil ) let poolSink = IncrementFiStakingConnectors.PoolSink( - staker: userAddress, + staker: userAddress, poolID: 1, uniqueID: nil ) @@ -459,7 +448,6 @@ poolSink.depositCapacity(from: lpTokens) - **Set-and-Forget**: Automated compounding without manual intervention required. - **Optimal Conversion**: Zapper ensures efficient reward token to LP token conversion. - ## Safety Best Practices ### Always Check Capacity @@ -528,7 +516,7 @@ Tests individual connectors in isolation to verify they respect their constraint // Test individual components test("VaultSource should maintain minimum balance") { let source = VaultSource(min: 100.0, withdrawVault: vaultCap, uniqueID: nil) - + // Test minimum balance enforcement let available = source.minimumAvailable() assert(available >= 100.0, message: "Should maintain minimum balance") @@ -547,7 +535,7 @@ test("Reward harvesting workflow should complete successfully") { swapper: swapper, sink: sink ) - + let result = workflow.execute() assert(result.success, message: "Workflow should complete successfully") } @@ -564,14 +552,14 @@ test("Strategy should handle price volatility") { priceOracle: mockPriceOracle, swapper: mockSwapper ) - + // Simulate price changes mockPriceOracle.setPrice(1.0) let result1 = strategy.execute() - + mockPriceOracle.setPrice(2.0) let result2 = strategy.execute() - + assert(result1 != result2, message: "Strategy should adapt to price changes") } ``` @@ -591,5 +579,6 @@ In this tutorial, you learned how to combine Flow Actions primitives to create s Composability is the core strength of Flow Actions. These examples demonstrate how Flow Actions primitives can be combined to create powerful, automated workflows that integrate multiple protocols seamlessly. The framework's standardized interfaces enable developers to chain operations together like LEGO blocks, focusing on strategy implementation rather than protocol-specific integration details. + [FLIP 339]: https://github.com/onflow/flips/pull/339/files -[5 Flow Actions Primitives]: intro-to-flow-actions.md \ No newline at end of file +[5 Flow Actions Primitives]: intro-to-flow-actions.md diff --git a/docs/blockchain-development-tutorials/forte/flow-actions/connectors.md b/docs/blockchain-development-tutorials/forte/flow-actions/connectors.md index 0f2e8d19fa..b8704da6fe 100644 --- a/docs/blockchain-development-tutorials/forte/flow-actions/connectors.md +++ b/docs/blockchain-development-tutorials/forte/flow-actions/connectors.md @@ -16,17 +16,7 @@ keywords: # Connectors -:::warning - -We are reviewing and finalizing Flow Actions in [FLIP 339]. The specific implementation may change as a part of this process. - -We will update these tutorials, but you may need to refactor your code if the implementation changes. - -::: - -## Overview - -**Connectors** are the bridge between external DeFi protocols and the standardized Flow Actions primitive interfaces. They act as **protocol adapters** that translate protocol-specific APIs into the universal language of Flow Actions. Think of them as "drivers" that provide a connection between software and a piece of hardware without the software developer needing to know how the hardware expects to receive commands, or an MCP allowing an agent to use an API in a standardized manner. +**Connectors** are the bridge between external DeFi protocols and the standardized Flow Actions primitive interfaces. They act as **protocol adapters** that translate protocol-specific APIs into the universal language of Flow Actions. Think of them as "drivers" that provide a connection between software and a piece of hardware without the software developer needing to know how the hardware expects to receive commands, or an MCP allowing an agent to use an API in a standardized manner. Flow Actions act as "money LEGOs" with which you can compose various complex operations with simple transactions. These are the benefits of connectors: @@ -53,7 +43,7 @@ Each connector implements one or more of the five primitive interfaces: access(all) struct MyProtocolSink: DeFiActions.Sink { // Protocol-specific configuration access(self) let protocolConfig: MyProtocol.Config - + // DeFiActions required methods access(all) fun getSinkType(): Type { ... } access(all) fun minimumCapacity(): UFix64 { ... } @@ -71,7 +61,7 @@ fun setID(_ id: UniqueIdentifier?) // Type-specific methods fun getSinkType(): Type // Sink only -fun getSourceType(): Type // Source only +fun getSourceType(): Type // Source only fun inType() / outType(): Type // Swapper only // Core operations @@ -95,44 +85,44 @@ ProtocolA.RewardsSource → SwapConnectors.SwapSource → ProtocolB.StakingSink ## Connector Library - 🔄 SOURCE Primitive Implementations +🔄 SOURCE Primitive Implementations -| Connector | Location | Protocol | Purpose | -|-----------|----------|----------|---------| -| VaultSource | [FungibleTokenConnectors] | Generic FungibleToken | Withdraw from vaults with minimum balance protection. | -| VaultSinkAndSource | [FungibleTokenConnectors] | Generic FungibleToken | Combined vault operations (dual interface). | -| SwapSource | [SwapConnectors] | Generic (composes with Swappers) | Source tokens then swap before returning. | -| PoolRewardsSource | [IncrementFiStakingConnectors] | IncrementFi Staking | Claim staking rewards from pools. | +| Connector | Location | Protocol | Purpose | +| ------------------ | ------------------------------ | -------------------------------- | ----------------------------------------------------- | +| VaultSource | [FungibleTokenConnectors] | Generic FungibleToken | Withdraw from vaults with minimum balance protection. | +| VaultSinkAndSource | [FungibleTokenConnectors] | Generic FungibleToken | Combined vault operations (dual interface). | +| SwapSource | [SwapConnectors] | Generic (composes with Swappers) | Source tokens then swap before returning. | +| PoolRewardsSource | [IncrementFiStakingConnectors] | IncrementFi Staking | Claim staking rewards from pools. | - ⬇️ SINK Primitive Implementations +⬇️ SINK Primitive Implementations -| Connector | Location | Protocol | Purpose | -|-----------|----------|----------|---------| -| VaultSink | [FungibleTokenConnectors] | Generic FungibleToken | Deposit to vaults with capacity limits. | -| VaultSinkAndSource | [FungibleTokenConnectors] | Generic FungibleToken | Combined vault operations (dual interface). | -| SwapSink | [SwapConnectors] | Generic (composes with Swappers) | Swap tokens before depositing to inner sink. | -| PoolSink | [IncrementFiStakingConnectors] | IncrementFi Staking | Stake tokens in staking pools. | +| Connector | Location | Protocol | Purpose | +| ------------------ | ------------------------------ | -------------------------------- | -------------------------------------------- | +| VaultSink | [FungibleTokenConnectors] | Generic FungibleToken | Deposit to vaults with capacity limits. | +| VaultSinkAndSource | [FungibleTokenConnectors] | Generic FungibleToken | Combined vault operations (dual interface). | +| SwapSink | [SwapConnectors] | Generic (composes with Swappers) | Swap tokens before depositing to inner sink. | +| PoolSink | [IncrementFiStakingConnectors] | IncrementFi Staking | Stake tokens in staking pools. | - 🔀 SWAPPER Primitive Implementations +🔀 SWAPPER Primitive Implementations -| Connector | Location | Protocol | Purpose | -|-----------|----------|----------|---------| -| MultiSwapper | [SwapConnectors] | Generic (DEX aggregation) | Aggregate multiple swappers for optimal routing. | -| Swapper | [IncrementFiSwapConnectors] | IncrementFi DEX | Token swapping through SwapRouter. | -| Zapper | [IncrementFiPoolLiquidityConnectors] | IncrementFi Pools | Single-token liquidity provision. | -| UniswapV2EVMSwapper | [UniswapV2SwapConnectors] | Flow EVM Bridge | Cross-VM UniswapV2-style swapping. | +| Connector | Location | Protocol | Purpose | +| ------------------- | ------------------------------------ | ------------------------- | ------------------------------------------------ | +| MultiSwapper | [SwapConnectors] | Generic (DEX aggregation) | Aggregate multiple swappers for optimal routing. | +| Swapper | [IncrementFiSwapConnectors] | IncrementFi DEX | Token swapping through SwapRouter. | +| Zapper | [IncrementFiPoolLiquidityConnectors] | IncrementFi Pools | Single-token liquidity provision. | +| UniswapV2EVMSwapper | [UniswapV2SwapConnectors] | Flow EVM Bridge | Cross-VM UniswapV2-style swapping. | - 💰 PRICEORACLE Primitive Implementations +💰 PRICEORACLE Primitive Implementations -| Connector | Location | Protocol | Purpose | -|-----------|----------|----------|---------| +| Connector | Location | Protocol | Purpose | +| ----------- | ---------------------- | ------------- | ----------------------------------------------- | | PriceOracle | [BandOracleConnectors] | Band Protocol | External price feeds with staleness validation. | - ⚡ FLASHER Primitive Implementations +⚡ FLASHER Primitive Implementations -| Connector | Location | Protocol | Purpose | -|-----------|----------|----------|---------| -| Flasher | [IncrementFiFlashloanConnectors] | IncrementFi DEX | Flash loans through SwapPair contracts. | +| Connector | Location | Protocol | Purpose | +| --------- | -------------------------------- | --------------- | --------------------------------------- | +| Flasher | [IncrementFiFlashloanConnectors] | IncrementFi DEX | Flash loans through SwapPair contracts. | ## Guide to Building Connectors @@ -140,13 +130,13 @@ ProtocolA.RewardsSource → SwapConnectors.SwapSource → ProtocolB.StakingSink First, determine which Flow Actions primitive(s) your connector will implement: -| Primitive | When to Use | Example Use Cases | -|-----------|-------------|-------------------| -| **Source** | Your protocol provides tokens | Vault withdrawals, reward claiming, unstaking. | -| **Sink** | Your protocol accepts tokens | Vault deposits, staking, loan repayments. | -| **Swapper** | Your protocol exchanges tokens | DEX trades, cross-chain bridges, LP provision. | -| **PriceOracle** | Your protocol provides price data | Oracle feeds, TWAP calculations. | -| **Flasher** | Your protocol offers flash loans | Arbitrage opportunities, liquidations. | +| Primitive | When to Use | Example Use Cases | +| --------------- | --------------------------------- | ---------------------------------------------- | +| **Source** | Your protocol provides tokens | Vault withdrawals, reward claiming, unstaking. | +| **Sink** | Your protocol accepts tokens | Vault deposits, staking, loan repayments. | +| **Swapper** | Your protocol exchanges tokens | DEX trades, cross-chain bridges, LP provision. | +| **PriceOracle** | Your protocol provides price data | Oracle feeds, TWAP calculations. | +| **Flasher** | Your protocol offers flash loans | Arbitrage opportunities, liquidations. | ### Analyze Your Protocol @@ -175,6 +165,7 @@ Create your connector struct implementing the chosen primitive interface(s). ### Add Safety Features Implement safety mechanisms: + - **Capacity checking** before operations - **Balance validation** after operations - **Graceful error handling** with no-ops @@ -183,6 +174,7 @@ Implement safety mechanisms: ### Support Flow Actions Standards Add required Flow Actions support: + - **IdentifiableStruct** implementation - **UniqueIdentifier** management - **ComponentInfo** for introspection @@ -205,7 +197,7 @@ access(all) fun minimumCapacity(): UFix64 { return 0.0 // Graceful failure } -// Bad: Panics on failure +// Bad: Panics on failure access(all) fun minimumCapacity(): UFix64 { let pool = self.poolCapability.borrow()! // Will panic if invalid return pool.getAvailableCapacity() @@ -223,14 +215,14 @@ access(all) fun depositCapacity(from: auth(FungibleToken.Withdraw) &{FungibleTok // Check capacity first let capacity = self.minimumCapacity() if capacity == 0.0 { return } - + // Calculate actual deposit amount let availableAmount = from.balance let depositAmount = capacity < availableAmount ? capacity : availableAmount - + // Handle edge case if depositAmount == 0.0 { return } - + // Proceed with deposit... } ``` @@ -247,14 +239,14 @@ access(all) fun depositCapacity(from: auth(FungibleToken.Withdraw) &{FungibleTok if from.getType() != self.getSinkType() { return // No-op for wrong token type } - + // Continue with deposit... } ``` ### **Event Integration** -- **Leverage Post-conditions**: Flow Actions interfaces emit events automatically. +- **Leverage Post-conditions**: Flow Actions interfaces emit events automatically. - **Provide Context**: Include relevant information in events. - **Support Traceability**: Use UniqueIdentifiers consistently. @@ -283,7 +275,7 @@ We will now go over how to build a connector and integrate it with Flow Actions. The `VaultSink` connector is already deployed and working in Flow Actions. Let's examine how it's integrated: **Location**: `cadence/contracts/connectors/FungibleTokenConnectors.cdc` -**Contract**: `FungibleTokenConnectors` +**Contract**: `FungibleTokenConnectors` **Connector**: `VaultSink` struct that defines the interaction with the connector. ### Deploy Your Connector Contract @@ -293,6 +285,7 @@ Deploy your connector contract with the following command: ```bash flow project deploy ``` + In your 'flow.json' you will find: ```json @@ -326,14 +319,14 @@ transaction(maxBalance: UFix64) { let vaultCap = signer.capabilities.get<&{FungibleToken.Receiver}>( /public/flowTokenReceiver ) - + // Create the VaultSink connector let vaultSink = FungibleTokenConnectors.VaultSink( max: maxBalance, depositVault: vaultCap, uniqueID: nil ) - + // Save to storage for later use signer.storage.save(vaultSink, to: /storage/FlowTokenVaultSink) } @@ -374,10 +367,10 @@ transaction(receiver: Address, vaultPublicPath: PublicPath, sinkStoragePath: Sto depositVault: self.depositVault, // Where tokens will be deposited uniqueID: nil // No unique ID for this example ) - + // Save the connector for later use self.signer.storage.save(sink, to: sinkStoragePath) - + log("VaultSink created and saved!") log("Max capacity: ".concat(max?.toString() ?? "unlimited")) log("Receiver: ".concat(receiver.toString())) @@ -416,16 +409,16 @@ transaction(depositAmount: UFix64) { let sink = signer.storage.borrow<&FungibleTokenConnectors.VaultSink>( from: /storage/FlowTokenSink ) ?? panic("VaultSink not found - create one first!") - + // 2. Create a simple source (your own vault) let flowVault = signer.storage.borrow( from: /storage/FlowTokenVault ) ?? panic("FlowToken vault not found") - + // 3. Check sink capacity before depositing let capacity = sink.minimumCapacity() log("Sink capacity: ".concat(capacity.toString())) - + if capacity >= depositAmount { // 4. Execute Source → Sink workflow let tokens <- flowVault.withdraw(amount: depositAmount) @@ -445,7 +438,7 @@ You can use VaultSink in advanced Flow Actions workflows: ```cadence // Example: VaultSink in AutoBalancer (real integration pattern) import "DeFiActions" -import "FungibleTokenConnectors" +import "FungibleTokenConnectors" import "BandOracleConnectors" transaction() { @@ -453,14 +446,14 @@ transaction() { // 1. Create rebalancing sink using VaultSink pattern let rebalanceCap = getAccount(signer.address) .capabilities.get<&{FungibleToken.Receiver}>(/public/FlowTokenReceiver) - + let rebalanceSink = FungibleTokenConnectors.VaultSink( max: nil, // No limit for rebalancing depositVault: rebalanceCap, uniqueID: nil ) - - // 2. Create rebalancing source + + // 2. Create rebalancing source let sourceCap = signer.capabilities.storage.issue( /storage/FlowTokenVault ) @@ -469,7 +462,7 @@ transaction() { withdrawVault: sourceCap, uniqueID: nil ) - + // 3. Create price oracle let priceOracle = BandOracleConnectors.PriceOracle( unitOfAccount: Type<@FlowToken.Vault>(), @@ -477,7 +470,7 @@ transaction() { feeSource: rebalanceSource, uniqueID: nil ) - + // 4. Create AutoBalancer using VaultSink pattern let autoBalancer <- DeFiActions.createAutoBalancer( oracle: priceOracle, @@ -488,9 +481,9 @@ transaction() { rebalanceSource: rebalanceSource, // Uses VaultSource! uniqueID: nil ) - + signer.storage.save(<-autoBalancer, to: /storage/FlowAutoBalancer) - + log("AutoBalancer created using VaultSink/VaultSource pattern!") } } @@ -520,6 +513,7 @@ The Flow Actions framework provides a comprehensive set of connectors that succe This framework allows developers to build sophisticated DeFi strategies while maintaining the simplicity and reliability of standardized primitive interfaces. The modular design allows for easy extension to additional protocols while preserving composability and atomic execution guarantees. + [FLIP 339]: https://github.com/onflow/flips/pull/339/files [FungibleTokenConnectors]: https://github.com/onflow/FlowActions/blob/main/cadence/contracts/connectors/FungibleTokenConnectors.cdc [SwapConnectors]: https://github.com/onflow/FlowActions/blob/main/cadence/contracts/connectors/SwapConnectors.cdc @@ -528,4 +522,4 @@ This framework allows developers to build sophisticated DeFi strategies while ma [IncrementFiPoolLiquidityConnectors]: https://github.com/onflow/FlowActions/blob/main/cadence/contracts/connectors/increment-fi/IncrementFiPoolLiquidityConnectors.cdc [UniswapV2SwapConnectors]: https://github.com/onflow/FlowActions/blob/main/cadence/contracts/connectors/evm/UniswapV2SwapConnectors.cdc [BandOracleConnectors]: https://github.com/onflow/FlowActions/blob/main/cadence/contracts/connectors/band-oracle/BandOracleConnectors.cdc -[IncrementFiFlashloanConnectors]: https://github.com/onflow/FlowActions/blob/main/cadence/contracts/connectors/increment-fi/IncrementFiFlashloanConnectors.cdc \ No newline at end of file +[IncrementFiFlashloanConnectors]: https://github.com/onflow/FlowActions/blob/main/cadence/contracts/connectors/increment-fi/IncrementFiFlashloanConnectors.cdc diff --git a/docs/blockchain-development-tutorials/forte/flow-actions/flow-actions-transaction.md b/docs/blockchain-development-tutorials/forte/flow-actions/flow-actions-transaction.md index b3becc27b4..5d1e325265 100644 --- a/docs/blockchain-development-tutorials/forte/flow-actions/flow-actions-transaction.md +++ b/docs/blockchain-development-tutorials/forte/flow-actions/flow-actions-transaction.md @@ -17,17 +17,7 @@ keywords: # Flow Actions Transaction -:::warning - -We are reviewing and finalizing Flow Actions in [FLIP 339]. The specific implementation may change as a part of this process. - -We will update these tutorials, but you may need to refactor your code if the implementation changes. - -::: - -## Overview - -[Staking] is a simple way to participate in the blockchain process. You supply tokens to help with governance and, in return, you earn a share of the network's rewards. It's a way to grow unused assets and provides a much higher rate of return than a savings account. +[Staking] is a simple way to participate in the blockchain process. You supply tokens to help with governance and, in return, you earn a share of the network's rewards. It's a way to grow unused assets and provides a much higher rate of return than a savings account. :::warning @@ -239,7 +229,7 @@ let operationID: DeFiActions.UniqueIdentifier ### Prepare Phase -The `prepare` phase runs first in the transaction. You use it to set up and validate a Cadence transaction. It's also the only place where a transaction can interact with a user's account and the [resources] within. +The `prepare` phase runs first in the transaction. You use it to set up and validate a Cadence transaction. It's also the only place where a transaction can interact with a user's account and the [resources] within. **Pool Validation** verifies that the specified pool exists and is accessible. diff --git a/docs/blockchain-development-tutorials/forte/flow-actions/index.md b/docs/blockchain-development-tutorials/forte/flow-actions/index.md index 2ad7adebd1..bdd712f2e8 100644 --- a/docs/blockchain-development-tutorials/forte/flow-actions/index.md +++ b/docs/blockchain-development-tutorials/forte/flow-actions/index.md @@ -32,14 +32,6 @@ keywords: This series covers how to build decentralized finance (DeFi) applications using the Flow Actions framework, enabling developers to create composable DeFi workflows. These tutorials are part of the Forte network upgrade, which introduces new capabilities to the Flow blockchain. -:::warning - -We are reviewing and finalizing Flow Actions in [FLIP 339]. The specific implementation may change as a part of this process. - -We will update these tutorials, but you may need to refactor your code if the implementation changes. - -::: - ## Tutorials - **[Introduction to Flow Actions]** - Learn about Flow Actions, a suite of standardized Cadence interfaces that enable developers to compose complex DeFi workflows using small, reusable components. diff --git a/docs/blockchain-development-tutorials/forte/flow-actions/intro-to-flow-actions.md b/docs/blockchain-development-tutorials/forte/flow-actions/intro-to-flow-actions.md index 39dad84585..cce73d16f3 100644 --- a/docs/blockchain-development-tutorials/forte/flow-actions/intro-to-flow-actions.md +++ b/docs/blockchain-development-tutorials/forte/flow-actions/intro-to-flow-actions.md @@ -29,15 +29,6 @@ keywords: # Introduction to Flow Actions -:::warning - -We are reviewing and finalizing Flow Actions in [FLIP 339]. The specific implementation may change as a part of this process. - -We will update these tutorials, but you may need to refactor your code if the implementation changes. - -::: -## Overview - _Actions_ are a suite of standardized Cadence interfaces that allow developers to compose complex workflows, starting with decentralized finance (DeFi) workflows, by connecting small, reusable components. Actions provide a "LEGO" framework of blocks where each component performs a single operation (deposit, withdraw, swap, price lookup, flash loan) while maintaining composability with other components. This creates sophisticated workflows executable in a single atomic transaction. By using Flow Actions, developers can remove large amounts of tailored complexity from building DeFi apps and can instead focus on business logic using nouns and verbs. @@ -125,8 +116,6 @@ Many Flow Actions use these types to provide a safer method of working with toke ## Flow Actions - - The following Flow Actions standardize **usage** patterns for common defi-related tasks. By working with them, you - or Artificial Intelligence (AI) agents - can more easily write transactions and functionality regardless of the myriad of different ways each protocol works to accomplish these tasks. :::info diff --git a/docs/blockchain-development-tutorials/forte/index.md b/docs/blockchain-development-tutorials/forte/index.md index 3d0008da75..08692ba7d8 100644 --- a/docs/blockchain-development-tutorials/forte/index.md +++ b/docs/blockchain-development-tutorials/forte/index.md @@ -30,7 +30,7 @@ The Forte network upgrade introduces several features that expand Flow's capabil :::info -Forte is **live** on testnet and Mainnet. +Forte is **live** on emulator, testnet, and Mainnet. ::: diff --git a/docs/blockchain-development-tutorials/forte/scheduled-transactions/scheduled-transactions-introduction.md b/docs/blockchain-development-tutorials/forte/scheduled-transactions/scheduled-transactions-introduction.md index b3624a4524..da1fa1405d 100644 --- a/docs/blockchain-development-tutorials/forte/scheduled-transactions/scheduled-transactions-introduction.md +++ b/docs/blockchain-development-tutorials/forte/scheduled-transactions/scheduled-transactions-introduction.md @@ -17,8 +17,6 @@ keywords: # Introduction to Scheduled Transactions -# Overview - Flow, EVM, and other blockchains are a form of a **single** shared computer that anyone can use, with no admin privileges, super user roles, or complete control. For this to work, it must be impossible for any user to freeze the computer, on purpose or by accident. As a result, most blockchain computers, including EVM and Solana, aren't [Turing Complete], because they can't run an unbounded loop. Each transaction must occur within one block, and can't consume more gas than the limit.