diff --git a/docs/blockchain-development-tutorials/cadence/cadence-advantages/compose-with-cadence-transactions.md b/docs/blockchain-development-tutorials/cadence/cadence-advantages/compose-with-cadence-transactions.md index ff022c6a49..4c57c0d208 100644 --- a/docs/blockchain-development-tutorials/cadence/cadence-advantages/compose-with-cadence-transactions.md +++ b/docs/blockchain-development-tutorials/cadence/cadence-advantages/compose-with-cadence-transactions.md @@ -19,9 +19,7 @@ keywords: - Flowscan --- -# Compose wth Cadence Transactions - -## Overview +# Compose wth Cadence transactions In this tutorial, you'll **compose with someone else's contracts** on Flow testnet. You'll write a Cadence transaction that reads public state from a contract named `Counter` and only increments the counter when it is odd. Then you'll extend the transaction to mint NFTs when the counter is odd, demonstrating how to compose multiple contracts in a single transaction. Everything runs against testnet using the Flow CLI and the dependency manager. @@ -46,7 +44,7 @@ After you complete this guide, you will be able to: - Create: https://developers.flow.com/build/tools/flow-cli/commands#create-accounts - Fund: https://developers.flow.com/build/tools/flow-cli/commands#fund-accounts -## Getting Started +## Get started Create a [new project] with the [Flow CLI]: @@ -231,13 +229,13 @@ You could trigger this same transaction **from an app** and **signed by a wallet --- -## Extend with NFT Minting +## Extend with NFT minting Now let's take our composition to the next level by adding NFT minting functionality when the counter is odd. We'll use an example NFT contract that's already deployed on testnet. This is a silly use case, but it demonstrates the complex use cases you can add to your apps, after contract deployment, and even if you aren't the author of any of the contracts! -### Install the NFT Contract +### Install the NFT contract First, let's install the ExampleNFT contract dependency: @@ -251,7 +249,7 @@ This repository uses different deployments for core contracts than those that th ::: -### Understanding NFT Minting +### Understand NFT minting Let's look at how NFT minting works with this contract. The [MintExampleNFT transaction] shows the pattern: @@ -291,7 +289,7 @@ transaction( You can copy this functionality and adapt it for our use case. -### Update the IncrementIfOdd Transaction +### Update the IncrementIfOdd transaction Now let's update our `IncrementIfOdd` transaction to mint an NFT when the counter is odd. You can either modify the existing transaction or create a new one: @@ -341,7 +339,7 @@ transaction() { } ``` -### Setup NFT Collection +### Setup NFT collection Before you can mint NFTs, set up an NFT collection in your account. Create a transaction to do this: @@ -392,7 +390,7 @@ You may need to run the regular `IncrementCounter` transaction first to get an o flow transactions send cadence/transactions/IncrementCounter.cdc --signer testnet-account --network testnet ``` -### View Your NFT +### View your NFT Click the transaction link in the console to view the transaction in [testnet Flowscan]. After you run the transaction **while the counter is odd**, you'll see an NFT in the `Asset Transfers` tab. diff --git a/docs/blockchain-development-tutorials/cadence/cadence-advantages/native-data-availibility-with-cadence-scripts.md b/docs/blockchain-development-tutorials/cadence/cadence-advantages/native-data-availibility-with-cadence-scripts.md index c7c141392e..e0a1877199 100644 --- a/docs/blockchain-development-tutorials/cadence/cadence-advantages/native-data-availibility-with-cadence-scripts.md +++ b/docs/blockchain-development-tutorials/cadence/cadence-advantages/native-data-availibility-with-cadence-scripts.md @@ -23,8 +23,6 @@ keywords: # Native Data Availability With Cadence Scripts -## Overview - In Solidity, you can only retrieve data from **view** functions that the contract author anticipated and included in the original contract. If the exact query you want is not exposed, teams typically rely on a _data availability service_ such as The Graph, Covalent, Alchemy Enhanced APIs, Reservoir, or NFTScan to compute and serve that view. In Cadence, **scripts** are general-purpose read programs. They can traverse public account storage, read public capabilities, and compose types from multiple contracts to answer new questions without modifying those contracts. You are not limited to the pre-written surface area of a single contract's views. @@ -62,7 +60,7 @@ If you are new to [_Hybrid Custody_], the high-level idea is that in Cadence, a ::: -## Getting Started +## Get started Create a new Flow project and generate a script file: @@ -83,7 +81,7 @@ We will **revise one script file** in four passes, and run it after each step. T --- -## Querying the account to find child accounts +## Query the account to find child accounts To start, write a script that borrows the parent's _Hybrid Custody_ manager and returns the child addresses it controls. This verifies that imports resolve and that the parent account is configured as expected. @@ -427,7 +425,7 @@ This demonstrates how you can easily modify Cadence scripts to answer different - If you see empty results in Step 4, confirm `isTopShot` matches the identifiers you observed in Step 3. - If you are not using _Hybrid Custody_, you can adapt Steps 2-4 to use `getAccount(child)` and scan **publicly exposed** `{NonFungibleToken.CollectionPublic}` capabilities, but you will not be able to assert provider access. -## How This Compares to Solidity +## How This compares to Solidity - **Solidity views are fixed**: You can only retrieve what the contract author exposed via `view` or `pure` functions. If you need a different aggregation or cross-contract traversal, you typically rely on a _data availability service_ or write a new contract to expose that view. - **Cadence scripts are flexible**: You compose types across modules, traverse account storage, and read public capabilities at query time. You do not need to redeploy contracts to answer new questions. diff --git a/docs/blockchain-development-tutorials/cadence/cadence-advantages/upgrading-cadence-contracts.md b/docs/blockchain-development-tutorials/cadence/cadence-advantages/upgrading-cadence-contracts.md index c2588d28c9..279b7a8c33 100644 --- a/docs/blockchain-development-tutorials/cadence/cadence-advantages/upgrading-cadence-contracts.md +++ b/docs/blockchain-development-tutorials/cadence/cadence-advantages/upgrading-cadence-contracts.md @@ -18,8 +18,6 @@ keywords: # Upgrading Cadence Contracts -## Overview - In Cadence, you can upgrade deployed contracts by adding new functionality while preserving existing state and maintaining the same contract address. Unlike other blockchain platforms that require complex proxy patterns or complete redeployment, Cadence allows you to seamlessly extend your contracts with new functions and events through multiple incremental upgrades. This tutorial demonstrates how to upgrade a deployed contract through two scenarios: @@ -45,11 +43,11 @@ After you complete this guide, you will be able to: - A **funded testnet account** to deploy and update contracts. - See [Create accounts] and [Fund accounts] in the Flow CLI commands. -## Contract Upgrade Overview +## Contract upgrade overview Cadence provides a sophisticated contract upgrade system that allows you to modify deployed contracts while ensuring data consistency and preventing runtime crashes. It's crucial for successful upgrades that you understand what you can and can't change. -### What You CAN Upgrade +### What you CAN upgrade - **Add new functions** - Extend contract functionality with new methods. - **Add new events** - Emit additional events for monitoring and indexing. @@ -59,7 +57,7 @@ Cadence provides a sophisticated contract upgrade system that allows you to modi - **Change access modifiers** - Update visibility of functions and fields. - **Reorder existing fields** - Field order doesn't affect storage. -### What You CANNOT Upgrade +### What you CANNOT upgrade - **Add new fields** - Would cause runtime crashes when loading existing data. - **Change field types** - Would cause deserialization errors. @@ -67,7 +65,7 @@ Cadence provides a sophisticated contract upgrade system that allows you to modi - **Change enum structures** - Raw values must remain consistent. - **Change contract name** - Contract address must remain the same. -### Why These Restrictions Exist +### Why these restrictions exist The [Cadence Contract Updatability documentation](https://cadence-lang.org/docs/language/contract-updatability) explains that these restrictions prevent: @@ -78,7 +76,7 @@ The [Cadence Contract Updatability documentation](https://cadence-lang.org/docs/ The validation system ensures that existing stored data remains valid and accessible after upgrades. -## Getting Started +## Get started Create a new Flow project for this tutorial: @@ -89,7 +87,7 @@ flow init upgrading-contracts-tutorial Follow the prompts and create a `Basic Cadence project (no dependencies)` then open the new project in your editor. -### Create and Fund Testnet Account +### Create and fund testnet account You'll need a funded testnet account to deploy and update contracts. In a terminal in the root of your project folder: @@ -120,7 +118,7 @@ The faucet provides free testnet tokens for development and testing purposes. Th --- -## Deploy the Initial Counter Contract +## Deploy the initial counter contract To start, let's deploy a simple Counter contract to testnet. @@ -165,7 +163,7 @@ access(all) contract Counter { } ``` -### Configure Deployment +### Configure deployment Add testnet deployment configuration to your `flow.json`: @@ -210,7 +208,7 @@ Counter -> 0x9942a81bc6c3c5b7 (contract deployed successfully) 🎉 All contracts deployed successfully ``` -### Test the Initial Contract +### Test the initial contract Use the provided transaction to test initial functionality: @@ -280,11 +278,11 @@ Events: --- -## Upgrade the Contract - Part 1: Adding Event for Even Numbers +## Upgrade the contract - Part 1: Add event for even numbers Let's start with a realistic scenario: What if we've realized it's very important to our users that they know when the counter reaches an even number, but we forgot to add an event for that case? Let's add that functionality first. -### Modify the Counter Contract - First Upgrade +### Modify the Counter contract - first upgrade Update `cadence/contracts/Counter.cdc` to add the new event and enhance the existing `increment()` function: @@ -330,7 +328,7 @@ access(all) contract Counter { } ``` -### Key Changes Made - Part 1 +### Key changes made - part 1 This first upgrade adds: @@ -346,11 +344,11 @@ This demonstrates how you can add new behavior and modify existing function beha --- -## Update the Deployed Contract - Part 1 +## Update the deployed contract - Part 1 Now let's update the deployed contract on testnet using the Flow CLI update command with our first upgrade. -### Update the Contract +### Update the contract Use the [Flow CLI update contract command] to upgrade your deployed contract: @@ -389,7 +387,7 @@ The contract successfully updated! Notice that: ::: -### Test the First Upgrade +### Test the first upgrade Let's test the new event functionality. Create a simple transaction to test the enhanced `increment()` function: @@ -429,11 +427,11 @@ Notice that: --- -## Upgrade the Contract - Part 2: Adding More Functionality +## Upgrade the contract - Part 2: add more functionality Now that we've successfully added the even number event, let's add more functionality to our contract. This demonstrates how you can make multiple incremental upgrades to extend your contract's capabilities. -### Modify the Counter Contract - Second Upgrade +### Modify the Counter contract - second upgrade Update `cadence/contracts/Counter.cdc` to add the additional functionality: @@ -502,7 +500,7 @@ access(all) contract Counter { } ``` -### Key Changes Made - Part 2 +### Key changes made - part 2 This second upgrade adds: @@ -513,11 +511,11 @@ This second upgrade adds: --- -## Update the Deployed Contract - Part 2 +## Update the deployed contract - Part 2 Now let's update the deployed contract with our second upgrade. -### Update the Contract Again +### Update the contract again Use the [Flow CLI update contract command] to upgrade your deployed contract with the additional functionality: @@ -557,7 +555,7 @@ The contract successfully updated again! Notice that: ::: -### Verify the Update +### Verify the update Let's verify that the existing functionality still works and the new functionality is available. @@ -599,11 +597,11 @@ Notice that: --- -## Test the New Functionality +## Test the new functionality Now let's create a transaction to test the new even counter functionality. -### Create Test Transaction +### Create test transaction Create a new transaction to test the upgraded functionality: @@ -651,7 +649,7 @@ transaction { } ``` -### Run the Test Transaction +### Run the test transaction Execute the transaction to test the new functionality: @@ -667,7 +665,7 @@ You will see logs that show: - The original `increment()` function still working normally - The new `CounterIncrementedToEven` event being emitted when incrementing results in an even number -### Verify Final State +### Verify final state Run the check script again to see the final state: @@ -689,11 +687,11 @@ This confirms that: --- -## Understanding Contract Upgrades in Cadence +## Understand contract upgrades in Cadence Cadence provides a sophisticated contract upgrade system that ensures data consistency while allowing controlled modifications. The [Cadence Contract Updatability documentation] provides comprehensive details about the validation rules and restrictions. -### What You Can Upgrade +### What you can upgrade When you upgrade Cadence contracts, you can: @@ -707,7 +705,7 @@ When you upgrade Cadence contracts, you can: - **Change access modifiers** of fields and functions - **Reorder existing fields** (order doesn't affect storage) -### What You Cannot Change +### What You cannot change There are important limitations to contract upgrades: @@ -734,9 +732,9 @@ The validation system focuses on preventing runtime inconsistencies with stored ::: -### Advanced Upgrade Patterns +### Advanced upgrade patterns -#### The `#removedType` Pragma +#### The `#removedType` pragma For cases where you need to remove a type declaration (which is normally invalid), Cadence provides the `#removedType` pragma. This allows you to "tombstone" a type, which prevents it from being re-added with the same name: @@ -755,7 +753,7 @@ This pragma: - **Cannot be removed** after you add it (prevents circumventing restrictions). - **Only works with composite types**, not interfaces. -#### Enum Upgrade Restrictions +#### Enum upgrade restrictions Enums have special restrictions due to their raw value representation: @@ -764,7 +762,7 @@ Enums have special restrictions due to their raw value representation: - **Cannot change the raw type** of an enum. - **Cannot change enum case names** (would change stored values' meaning). -### Best Practices +### Best practices When you upgrade contracts: @@ -779,7 +777,7 @@ When you upgrade contracts: --- -## Why This Matters +## Why this matters Cadence's contract upgrade model provides several advantages: 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 4e6fd269b0..84c92e96e6 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,9 +16,9 @@ keywords: sidebar_label: DeFi Math Utils --- -# High-Precision Fixed-Point 128 Bit Math +# High-precision fixed-point 128 bit math -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. @@ -26,11 +26,11 @@ Through integration of this math utility library, developers can ensure that the :::info -While this documentation focuses on DeFi use cases, you can use these mathematical utilities for any application requiring high-precision decimal arithmetic beyond the native 8-decimal limitation of `UFix64`. +While this document focuses on DeFi use cases, you can use these mathematical utilities for any application requiring high-precision decimal arithmetic beyond the native 8-decimal limitation of `UFix64`. ::: -## The Precision Problem +## The precision problem DeFi applications often require multiple sequential calculations, and each operation can introduce rounding errors. When these errors compound over multiple operations, they can lead to: @@ -55,7 +55,7 @@ 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! -## The Solution: 24-Decimal Precision +## The solution: 24-decimal precision [`DeFiActionsMathUtils`] solves this with `UInt128` to represent fixed-point numbers with 24 decimal places (scaling factor of 10^24). This provides 16 additional decimal places for intermediate calculations, dramatically reducing precision loss. @@ -65,7 +65,7 @@ There is still some precision loss occurring, but it is much smaller than with e ::: -### The Three-Tier Precision System +### The three-tier precision system The contract implements a precision sandwich pattern: @@ -89,7 +89,7 @@ let result = DeFiActionsMathUtils.mul(highPrecision, anotherValue) let output = DeFiActionsMathUtils.toUFix64Round(result) ``` -## Core Constants +## Core constants The contract defines several key constants: @@ -101,7 +101,7 @@ access(all) let decimals: UInt8 // 24 These constants ensure consistent scaling across all operations. -## Rounding Modes +## Rounding modes Smart rounding is the strategic selection of rounding strategies based on the financial context of your calculation. After performing high-precision calculations at 24 decimals, you must convert the final results back to `UFix64` (8 decimals). How you handle this conversion can protect your protocol from losses, ensure fairness to users, and reduce systematic bias. @@ -123,7 +123,7 @@ access(all) enum RoundingMode: UInt8 { } ``` -### When to Use Each Mode +### When to use each mode **RoundDown** - Choose this when you calculate user payouts, withdrawals, or rewards. When you round down, your protocol retains any fractional amounts, which protects against losses from accumulated rounding errors. This is the conservative choice when funds leave your protocol. @@ -153,11 +153,11 @@ let displayValue = DeFiActionsMathUtils.toUFix64Round(calculatedValue) let unbiasedValue = DeFiActionsMathUtils.toUFix64(calculatedValue, DeFiActionsMathUtils.RoundingMode.RoundEven) ``` -## Core Functions +## Core functions -### Conversion Functions +### Conversion functions -**Converting UFix64 to UInt128** +**Convert UFix64 to UInt128** ```cadence access(all) view fun toUInt128(_ value: UFix64): UInt128 @@ -175,7 +175,7 @@ let highPrecisionPrice = DeFiActionsMathUtils.toUInt128(price) // highPrecisionPrice = 123456789000000000000000000 (represents 123.45678900... with 24 decimals) ``` -**Converting UInt128 to UFix64** +**Convert UInt128 to UFix64** ```cadence access(all) view fun toUFix64(_ value: UInt128, _ roundingMode: RoundingMode): UFix64 @@ -200,7 +200,7 @@ let ceilingValue = DeFiActionsMathUtils.toUFix64RoundUp(highPrecisionValue) // ceilingValue = 1234567.89012346 (rounded up to 8 decimals) ``` -## High-Precision Arithmetic +## High-precision arithmetic ### Multiplication @@ -251,7 +251,7 @@ let result = DeFiActionsMathUtils.toUFix64Round(pricePerShare) // result = 500.0 ``` -### UFix64 Division with Rounding +### UFix64 division with rounding For convenience, the contract provides direct division functions that handle conversion and rounding in one call: @@ -281,11 +281,11 @@ let perUserFee = DeFiActionsMathUtils.divUFix64WithRoundingUp(totalAmount, numbe // perUserFee = 333.33333334 ``` -## Common DeFi Use Cases +## Common DeFi use cases -### Liquidity Pool Pricing (Constant Product AMM) +### Liquidity pool pricing (constant product AMM) -Automated Market Makers like Uniswap use the formula `x * y = k`. Here's how to calculate swap outputs with high precision: +Automated Market Makers (AMM) like Uniswap use the formula `x * y = k`. Here's how to calculate swap outputs with high precision: ```cadence import DeFiActionsMathUtils from 'ContractAddress' @@ -325,7 +325,7 @@ access(all) fun calculateSwapOutput( } ``` -### Compound Interest Calculations +### Compound interest calculations Calculate compound interest for yield farming rewards: @@ -362,7 +362,7 @@ access(all) fun calculateCompoundInterest( } ``` -### Proportional Distribution +### Proportional distribution Distribute rewards proportionally among stakeholders: @@ -388,7 +388,7 @@ access(all) fun calculateProportionalShare( } ``` -### Price Impact Calculation +### Price impact calculation Calculate the price impact of a large trade: @@ -424,9 +424,9 @@ access(all) fun calculatePriceImpact( } ``` -## Benefits of High-Precision Math +## Benefits of high-precision math -### Precision Preservation +### Precision preservation The 24-decimal precision provides headroom for complex calculations: @@ -439,7 +439,7 @@ let step4 = DeFiActionsMathUtils.div(step3, valueE) // Still maintains 24 decimals of precision until final conversion ``` -### Overflow Protection +### Overflow protection The contract uses `UInt256` for intermediate multiplication to prevent overflow: @@ -462,7 +462,7 @@ access(all) view fun assertWithinUFix64Bounds(_ value: UInt128) { } ``` -## Best Practices +## Best practices Always Use High Precision for Intermediate Calculations. @@ -506,7 +506,7 @@ access(all) fun swap(inputAmount: UFix64) { } ``` -## More Resources +## More resources - [View the DeFiActionsMathUtils source code] - [Flow DeFi Actions Documentation] 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 0ab20171f3..b8a5dc06fb 100644 --- a/docs/blockchain-development-tutorials/forte/flow-actions/basic-combinations.md +++ b/docs/blockchain-development-tutorials/forte/flow-actions/basic-combinations.md @@ -9,7 +9,15 @@ keywords: - examples --- -# Composing Workflows with Flow Actions +# 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. + +::: 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: @@ -23,7 +31,7 @@ Flow Actions are designed to be **composable**, which means you can chain them t - **Flasher** → Issues flash loans that must be repaid within the same transaction via callback execution. Flashers enable capital-efficient strategies like arbitrage and liquidations without requiring upfront capital. -## Learning Objectives +## Learning objectives After you complete this tutorial, you will be able to: @@ -36,7 +44,7 @@ After you complete this tutorial, you will be able to: - Use UniqueIdentifiers to trace and correlate operations across multiple Flow Actions. - Compose complex DeFi workflows by connecting multiple Actions in a single atomic transaction. -## Core Flow Patterns +## Core Flow patterns ### Linear Flow (Source → Swapper → Sink) @@ -72,9 +80,9 @@ Source C ↗ **Example**: Multiple DEX aggregators finding the best swap route. -## Common DeFi Workflow Combinations +## Common DeFi workflow combinations -### Single Token to LP (Zapper) +### Single token to LP (Zapper) **Goal**: Convert a single token into liquidity provider (LP) tokens in one transaction. @@ -112,7 +120,7 @@ let lpTokens <- zapper.swap(nil, inVault: <-flowTokens) - **Efficiency**: Automatically calculates optimal split ratios. - **Composability**: Output LP tokens work with any sink connector. -### Reward Harvesting & Conversion +### Reward harvesting and conversion **Goal**: Claim staking rewards and convert them to a stable token. @@ -162,7 +170,7 @@ vaultSink.depositCapacity(from: &stableTokens) - **Automation**: Single transaction handles claim, swap, and storage. - **Capital Efficiency**: No manual intervention needed for reward management. -### Liquidity Provision & Yield Farming +### Liquidity provision & yield farming **Goal**: Convert single token to LP tokens for yield farming @@ -210,7 +218,7 @@ stakingSink.depositCapacity(from: &lpTokens) - **Single Transaction**: No need for multiple manual steps or approvals. - **Automatic Staking**: LP tokens immediately start earning rewards. -### Cross-VM Bridge & Swap +### Cross-VM bridge and swap **Goal**: Bridge tokens from Cadence to EVM, swap them, then bridge back. @@ -261,7 +269,7 @@ cadenceSink.depositCapacity(from: &evmTokens) - **Cross-VM Arbitrage**: Exploit price differences between VM environments. - **Atomic Execution**: All bridging and swapping happens in single transaction. -### Flash Loan Arbitrage +### Flash loan arbitrage **Goal**: Borrow tokens, execute arbitrage, repay loan with profit. @@ -301,9 +309,9 @@ flasher.flashLoan(1000.0, callback: arbitrageCallback) - **Risk-Free Profit**: Transaction reverts if arbitrage isn't profitable. - **Market Efficiency**: Helps eliminate price discrepancies across DEXs. -## Advanced Workflow Combinations +## Advanced Wwrkflow combinations -### Vault Source + Zapper Integration +### VaultSource + Zapper integration **Goal**: Withdraw tokens from a vault and convert them to LP tokens in a single transaction. @@ -350,7 +358,7 @@ log("LP tokens created: ".concat(lpTokens.balance.toString())) - **Single Transaction**: Complex multi-step process executed atomically. - **Minimum Protection**: VaultSource ensures vault never goes below safety threshold. -### Price-Informed Rebalancing +### Price-informed rebalancing **Goal**: Create autonomous rebalancing system based on price feeds. @@ -393,7 +401,7 @@ autoBalancer.rebalance(force: false) // Autonomous rebalancing - **Market Responsive**: Adapts to price movements with real-time oracle data. - **Threshold Flexibility**: Configurable upper/lower bounds for different risk profiles. -### Restake & Compound Strategy +### Restake and compound strategy **Goal**: Automatically compound staking rewards back into the pool. @@ -448,9 +456,9 @@ 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 +## Safety best practices -### Always Check Capacity +### Always check capacity Prevents transaction failures and allows graceful handling when sinks reach their maximum capacity limits. This is crucial for automated workflows that might encounter varying capacity conditions. @@ -463,7 +471,7 @@ if sink.depositCapacity(from: &vault) { } ``` -### Validate Balances +### Validate balances Ensures operations behave as expected and helps detect unexpected token loss or gain during complex workflows. Balance validation is essential for financial applications where token accuracy is critical. @@ -476,7 +484,7 @@ let afterBalance = vault.balance assert(afterBalance >= beforeBalance, message: "Balance should not decrease") ``` -### Use Graceful Degradation +### Use graceful degradation Prevents entire workflows from failing when individual components encounter issues. This approach allows robust strategies that can adapt to changing market conditions or temporary protocol unavailability. @@ -490,7 +498,7 @@ if let result = try? operation.execute() { } ``` -### Resource Management +### Resource management Proper resource cleanup prevents token loss and ensures all vaults are properly handled, even when transactions partially fail. This is critical in Cadence where you must explicitly manage resources. @@ -506,9 +514,9 @@ defer { } ``` -## Testing Your Combinations +## Testing your combinations -### Unit Testing +### Unit testing Tests individual connectors in isolation to verify they respect their constraints and behave correctly under various conditions. This catches bugs early and ensures each component works as designed. @@ -523,7 +531,7 @@ test("VaultSource should maintain minimum balance") { } ``` -### Integration Testing +### Integration testing Validates that multiple connectors work together correctly in complete workflows. This ensures the composition logic is sound and identifies issues that only appear when components interact. @@ -541,7 +549,7 @@ test("Reward harvesting workflow should complete successfully") { } ``` -### Simulation Testing +### Simulation testing Tests strategies under various market conditions using mock data to verify they respond appropriately to price changes, liquidity variations, and other market dynamics. This is essential for strategies that rely on external market data. @@ -564,7 +572,7 @@ test("Strategy should handle price volatility") { } ``` -## 📚 Next Steps +## 📚 Next steps Now that you understand basic combinations, explore: diff --git a/docs/blockchain-development-tutorials/forte/flow-actions/connectors.md b/docs/blockchain-development-tutorials/forte/flow-actions/connectors.md index b8704da6fe..c2705f8ff7 100644 --- a/docs/blockchain-development-tutorials/forte/flow-actions/connectors.md +++ b/docs/blockchain-development-tutorials/forte/flow-actions/connectors.md @@ -16,7 +16,15 @@ keywords: # Connectors -**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. +:::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. + +::: + +**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: @@ -24,9 +32,9 @@ Flow Actions act as "money LEGOs" with which you can compose various complex ope - Standardized Interface: All connectors implement the same core methods, which makes them interchangeable. - Protocol Integration: They handle the complex interactions with different DeFi services (swaps, staking, lending, and so on). -## How Connectors Work +## How connectors work -### Abstraction Layer +### Abstraction layer Connectors sit between your application logic and protocol-specific contracts: @@ -34,7 +42,7 @@ Connectors sit between your application logic and protocol-specific contracts: Your DeFi Strategy → Flow Actions Connector → Protocol Contract → Blockchain State ``` -### Interface Implementation +### Interface implementation Each connector implements one or more of the five primitive interfaces: @@ -74,7 +82,7 @@ fun getPrice(baseAsset: Type, quoteAsset: Type): UFix64 // PriceOracle fun flashLoan(amount: UFix64, callback: Function) // Flasher ``` -### Composition Pattern +### Composition pattern You can combine Connetors to create sophisticated workflows: @@ -124,9 +132,9 @@ ProtocolA.RewardsSource → SwapConnectors.SwapSource → ProtocolB.StakingSink | --------- | -------------------------------- | --------------- | --------------------------------------- | | Flasher | [IncrementFiFlashloanConnectors] | IncrementFi DEX | Flash loans through SwapPair contracts. | -## Guide to Building Connectors +## Guide to building connectors -### Choose Your Primitive +### Choose your primitive First, determine which Flow Actions primitive(s) your connector will implement: @@ -138,7 +146,7 @@ First, determine which Flow Actions primitive(s) your connector will implement: | **PriceOracle** | Your protocol provides price data | Oracle feeds, TWAP calculations. | | **Flasher** | Your protocol offers flash loans | Arbitrage opportunities, liquidations. | -### Analyze Your Protocol +### Analyze your protocol Study your target protocol to understand: @@ -148,7 +156,7 @@ Study your target protocol to understand: - **Fee structures** and payment mechanisms - **Access controls** and permissions -### Design Your Connector +### Design your connector Plan your connector implementation: @@ -158,11 +166,11 @@ Plan your connector implementation: - **Resource management** for token handling - **Event emission** for traceability -### Implement the Interface +### Implement the interface Create your connector struct implementing the chosen primitive interface(s). -### Add Safety Features +### Add safety features Implement safety mechanisms: @@ -171,7 +179,7 @@ Implement safety mechanisms: - **Graceful error handling** with no-ops - **Resource cleanup** for empty vaults -### Support Flow Actions Standards +### Support Flow Actions standards Add required Flow Actions support: @@ -180,9 +188,9 @@ Add required Flow Actions support: - **ComponentInfo** for introspection - **Event emission** integration -## Best Practices +## Best practices -### **Error Handling** +### **Error handling** - **Graceful Failures**: Return empty results instead of panicking. - **Validation**: Check all inputs and preconditions. @@ -204,7 +212,7 @@ access(all) fun minimumCapacity(): UFix64 { } ``` -### **Capacity and Balance Checking** +### **Capacity and balance checking** - **Always Check First**: Validate capacity/availability before operations. - **Respect Limits**: Work within available constraints. @@ -227,7 +235,7 @@ access(all) fun depositCapacity(from: auth(FungibleToken.Withdraw) &{FungibleTok } ``` -### **Type Safety** +### **Type safety** - **Validate Types**: Ensure vault types match expected types. - **Early Returns**: Fail fast on type mismatches. @@ -244,13 +252,13 @@ access(all) fun depositCapacity(from: auth(FungibleToken.Withdraw) &{FungibleTok } ``` -### **Event Integration** +### **Event integration** - **Leverage Post-conditions**: Flow Actions interfaces emit events automatically. - **Provide Context**: Include relevant information in events. - **Support Traceability**: Use UniqueIdentifiers consistently. -### **Resource Management** +### **Resource management** - **Handle Empty Vaults**: Use `DeFiActionsUtils.getEmptyVault()` for consistent empty vault creation. - **Destroy Properly**: Clean up resources in all code paths. @@ -278,7 +286,7 @@ The `VaultSink` connector is already deployed and working in Flow Actions. Let's **Contract**: `FungibleTokenConnectors` **Connector**: `VaultSink` struct that defines the interaction with the connector. -### Deploy Your Connector Contract +### Deploy Your Connector contract Deploy your connector contract with the following command: @@ -303,7 +311,7 @@ In your 'flow.json' you will find: } ``` -### Create Usage Transactions +### Create usage transactions Create transaction templates for using your connectors: @@ -333,7 +341,7 @@ transaction(maxBalance: UFix64) { } ``` -### Real Usage Transaction: VaultSink +### Real usage transaction: VaultSink Here's the actual working transaction that creates a VaultSink: @@ -394,7 +402,7 @@ flow transactions send cadence/transactions/fungible-token-stack/save_vault_sink --signer emulator ``` -### Create Combinations Examples +### Create combinations examples Show how your connectors work with existing Flow Actions components: @@ -431,7 +439,7 @@ transaction(depositAmount: UFix64) { } ``` -### Add to Existing Workflows +### Add to existing workflows You can use VaultSink in advanced Flow Actions workflows: @@ -489,7 +497,7 @@ transaction() { } ``` -### For Your Own Connectors +### For Your own connectors When building your own connectors, follow the VaultSink pattern: 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 5d1e325265..ca723eca0c 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,7 +17,15 @@ keywords: # Flow Actions Transaction -[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 + +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. + +::: + +[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 @@ -41,7 +49,7 @@ If you combine this transaction with [scheduled transactions], you can automate ::: -## Learning Objectives +## Learning objectives After you complete this tutorial, you will be able to: @@ -55,11 +63,11 @@ After you complete this tutorial, you will be able to: - Flow CLI: install from the [Flow CLI docs] - Cursor + [Cadence Extension] (recommended) -## Cadence Programming Language +## Cadence programming language This tutorial assumes you have a modest knowledge of [Cadence]. If you don't, you can still follow along, but we recommend that you complete our series of [Cadence] tutorials. Most developers find it more pleasant than other blockchain languages and it's easy to pick up. -## Getting Started on Mainnet +## Getting started on mainnet This demo uses **mainnet** and a real DeFi protocol. Before you write any code, set up your staking position. @@ -73,7 +81,7 @@ This tutorial uses a real protocol with real funds. Only work with funds your co To complete this tutorial, set up a staking position in Increment Fi. If you already have LP tokens, skip to the **Staking LP Token** step. -**Creating an LP Position** +**Creating an LP position** First, go to the [Increment Fi Liquidity Pool] and select 'Single Asset' to provide liquidity with your FLOW tokens. @@ -81,7 +89,7 @@ First, go to the [Increment Fi Liquidity Pool] and select 'Single Asset' to prov Then, enter the amount of FLOW you want to add as liquidity. Confirm the transaction and continue to the next step. -**Staking LP Token** +**Staking LP token** Now that you have LP tokens from the FLOW-stFLOW pool, you can stake these tokens to receive rewards from them. To do this, go to the [IncrementFi Farms] page and look for the `Flow-stFlow Pool #199` pool. Note that the #199 is the Pool ID (pid). You might need to select the list view first (the middle button in the upper-right section of the LP pools page) in order to properly see the pid. @@ -97,7 +105,7 @@ Then, select `Stake LP` and enter the amount of LP tokens to stake into the pool Now our staking position generates rewards as time passes by. We use Flow Actions to execute a single transaction that can claim the rewards (stFLOW), convert the optimal amount into FLOW, increase the LP position (thus getting more LP tokens), and restake them into the farm. -### Initialize Your Staking User Certificate +### Initialize Your Staking.UserCertificate IncrementFi uses a `Staking.UserCertificate` internally for some actions, and you'll need this certificate to complete this tutorial. While the platform automatically creates it when you perform other actions on the platform, you can explicitly set it up with the [script on Flow Runner]. @@ -120,13 +128,13 @@ The UserCertificate is a resource stored in your account's private storage that: 1. Proves your identity for IncrementFi staking operations. 2. Allows you to claim rewards from staking pools. -## Setting Up the Project +## Set up the project To start, use the [Flow Actions Scaffold] repo as a template to create a new repository. Clone your new repository and open it in your editor. Follow the instructions in the README for **mainnet**. -### Starting With the Scaffold +### Start With the scaffold Create a new repo with the [Flow Actions Scaffold] as a template. Clone your new repo locally and open it in your editor. @@ -138,7 +146,7 @@ This Scaffold repo is a minimal Flow project with dependencies for Flow Actions ::: -### Export Your Wallet Key +### Export Your wallet key :::danger @@ -170,7 +178,7 @@ Create a `.pkey` file for your wallet key, **add it to `.gitignore`**, then add } ``` -## Building the Transaction +## Build the transaction Now that the dependencies have been properly setup and we have made sure that our account is properly setup, the staking position is established as well as the `Staking.UserCertificate`; we are now ready to finally build the restaking transaction @@ -184,7 +192,7 @@ The key pattern we need to create is: - **Swap**: Converts tokens (swapping to zap input then zapping to LP tokens) - **Sink**: Receives and deposits tokens (staking pools, vaults) -### Import Required Contracts +### Import required contracts First, import all the contracts you need to build the transaction: @@ -204,7 +212,7 @@ import "Staking" - `IncrementFiPoolLiquidityConnectors`: LP token creation (zapping) - `Staking`: Core staking contract for user certificates -### Define Transaction Parameters +### Define transaction parameters We will specify the `pid` (Pool ID) as the transaction parameter because it identifies which IncrementFi staking pool to interact with @@ -214,7 +222,7 @@ transaction( ) { ``` -### Declare Transaction Properties +### Declare transaction properties Then, declare all the properties needed for the transaction. Here is where you'll use the `Staking.UserCertificate` for authentication staking operations. The `pool` is used to reference the staking pool for validation. The starting balance for post-condition verification is the `startingStake`. The composable source that provides LP tokens is the `swapSource`. The `expectedStakeIncrease` is the minimum expected increase for safety. Finally, the `operationID` serves as the unique identifier for tracing the operation across Flow Actions. @@ -227,7 +235,7 @@ let expectedStakeIncrease: UFix64 let operationID: DeFiActions.UniqueIdentifier ``` -### Prepare Phase +### 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. @@ -262,7 +270,7 @@ self.userCertificateCap = acct.capabilities.storage self.operationID = DeFiActions.createUniqueIdentifier() ``` -### Token Type Detection and Configuration +### Token type detection and configuration Use the `pid` from the pool we staked the LP tokens to get the liquidity pair information (what tokens make up this pool). We also convert token identifiers to actual Cadence types and determines if this is a stableswap pool or a regular AMM. @@ -276,7 +284,7 @@ let token0Type = IncrementFiStakingConnectors.tokenTypeIdentifierToVaultType(pai let token1Type = IncrementFiStakingConnectors.tokenTypeIdentifierToVaultType(pair.getPairInfoStruct().token1Key) ``` -### Build the Flow Actions Chain +### Build the Flow Actions chain We need to create the `RewardsSource` so that we can claim the available rewards from the staking pool. @@ -330,7 +338,7 @@ self.expectedStakeIncrease = zapper.quoteOut( ).outAmount ``` -### Post-Condition Safety Check +### Post-condition safety check This phase runs at the end for condition verification. We verify that the transaction actually increased your staking balance as expected. @@ -343,7 +351,7 @@ post { } ``` -### Execute the Transaction +### Execute the transaction `poolSink` creates the staking pool sink in which the LP tokens are deposited. @@ -372,7 +380,7 @@ destroy vault See what happened? We executed this whole (and quite complex) flow in an atomic manner with a single transaction! -## Running the Transaction +## Run the transaction We are now ready to restake the position with a single transaction! @@ -385,7 +393,7 @@ flow transactions send cadence/transactions/increment_fi_restake.cdc \ Replace `` with your actual pool ID (PID) from the IncrementFi Farms page, in this case it is 1999. The PID changes over time. -### Interpreting the Results +### Interpret the results After you complete the transaction, you see that the following events occurred: @@ -395,7 +403,7 @@ After you complete the transaction, you see that the following events occurred: - LP tokens were received. - LP tokens were staked back into the #199 pool causing the staking balance to increase. -## Running the Transaction on Emulator +## Run the transaction on emulator You can run this whole transaction on Emulator as well. Although this example used a real pool to demonstrate a real-world use case, we recommend you start any real projects by testing on the Emulator. After cloning the [Flow Actions Scaffold] and installing the dependencies you can run: diff --git a/docs/blockchain-development-tutorials/forte/flow-actions/index.md b/docs/blockchain-development-tutorials/forte/flow-actions/index.md index bdd712f2e8..103ad02a3e 100644 --- a/docs/blockchain-development-tutorials/forte/flow-actions/index.md +++ b/docs/blockchain-development-tutorials/forte/flow-actions/index.md @@ -17,7 +17,7 @@ keywords: - composable defi --- -# Flow Actions Tutorials +# Flow Actions tutorials