<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Miracle656</title>
    <description>The latest articles on DEV Community by Miracle656 (@miracle656).</description>
    <link>https://dev.to/miracle656</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F974547%2F783fc96a-5163-4875-aac4-10295b6f77c4.jpeg</url>
      <title>DEV Community: Miracle656</title>
      <link>https://dev.to/miracle656</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/miracle656"/>
    <language>en</language>
    <item>
      <title>From Bitcoin User to Bitcoin Developer: What Six Weeks of Mastering Bitcoin Actually Taught Me</title>
      <dc:creator>Miracle656</dc:creator>
      <pubDate>Thu, 14 May 2026 16:54:26 +0000</pubDate>
      <link>https://dev.to/miracle656/from-bitcoin-user-to-bitcoin-developer-what-six-weeks-of-mastering-bitcoin-actually-taught-me-25dg</link>
      <guid>https://dev.to/miracle656/from-bitcoin-user-to-bitcoin-developer-what-six-weeks-of-mastering-bitcoin-actually-taught-me-25dg</guid>
      <description>&lt;p&gt;I've been around Bitcoin long enough to know the talking points. Decentralized. 21 million cap. Digital gold. But knowing the talking points and understanding the system are two very different things and I didn't fully appreciate that gap until I started the Btrust Builders Mastering Bitcoin pathway.&lt;/p&gt;

&lt;p&gt;Six weeks later, I think differently about Bitcoin. Not just what it is, but how it works, why it was designed that way, and what it actually takes to build on it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I thought I knew&lt;/strong&gt;&lt;br&gt;
Going in, I had developer experience and enough Bitcoin familiarity to feel comfortable in most conversations. I knew about Taproot. I'd heard of Lightning. I understood HD wallets at a surface level.&lt;/p&gt;

&lt;p&gt;What I didn't have was the connective tissue the why behind the design decisions, the tradeoffs that shaped the protocol, the mental models that make everything else make sense. That's what this pathway built.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The concept that changed everything: UTXOs&lt;/strong&gt;&lt;br&gt;
If I had to point to a single shift in how I think about Bitcoin, it's the UTXO model.&lt;/p&gt;

&lt;p&gt;Before this program, I thought about Bitcoin the way most people do: balances, accounts, sending and receiving. That framing is intuitive, but it's wrong. Bitcoin doesn't store balances anywhere. What exists on-chain is a set of unspent transaction outputs, discrete chunks of value, each locked with a spending condition. Your "balance" is just the sum of UTXOs your keys can unlock.&lt;/p&gt;

&lt;p&gt;That reframe changes everything. It changes how you think about privacy (address reuse links your UTXOs together publicly). It changes how you think about fees (they're the implied difference between inputs and outputs never explicitly stated). It changes how you think about wallet design, transaction construction, and even the economics of small payments.&lt;/p&gt;

&lt;p&gt;Once the UTXO model clicked, a lot of things that seemed arbitrary started making sense.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The part that actually challenged me&lt;/strong&gt;&lt;br&gt;
I expected cryptography to be the hard part. The elliptic curve math, the key derivation, the signature schemes. And those did require work of understanding BIP32 child key derivation, why the chain code exists, what makes a hardened child key different, none of that came immediately.&lt;/p&gt;

&lt;p&gt;But the thing that genuinely tripped me up was Schnorr multisig and the key cancellation attack. The concept is subtle: in a naive Schnorr aggregation scheme, a malicious participant can choose their public key after seeing yours, in a way that cancels out your contribution to the aggregate key. The fix — committing to all public keys before sharing, is simple to describe but took me a while to really internalize why it works mathematically.&lt;/p&gt;

&lt;p&gt;Working through it required slowing down, going back to first principles, and actually sitting with the discomfort of not immediately understanding something. That process — not the answer itself — was probably the most valuable part of the program.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Taproot: when it all came together&lt;/strong&gt;&lt;br&gt;
By the time I got to Taproot, I had enough context for it to feel like a payoff.&lt;/p&gt;

&lt;p&gt;Taproot combines three ideas: key aggregation (via Schnorr), script hiding (via MAST), and key tweaking (via Pay-to-Contract). The result is that any Taproot spend, whether it's a simple single-signature payment or a complex multisig arrangement with timelocks and fallback conditions — looks identical on-chain when the happy path is taken.&lt;/p&gt;

&lt;p&gt;That's not just clever engineering. It's a philosophical statement about what Bitcoin Script should be: expressive enough to handle complex conditions, but private enough that those conditions don't need to be broadcast to the world unless something goes wrong.&lt;/p&gt;

&lt;p&gt;Understanding Taproot properly required understanding everything that came before it. That's what made it satisfying.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How I'm thinking about Bitcoin differently now&lt;/strong&gt;&lt;br&gt;
The biggest shift is moving from thinking about Bitcoin as a product to thinking about it as a protocol.&lt;/p&gt;

&lt;p&gt;A product is something you use. A protocol is something you build on, extend, and reason about. The questions that interest me now are different ones: How do wallets decide what fee rate to target? What does a real-world Tapscript spending condition look like in practice? How does Lightning actually handle multisig today, given that MuSig2 deployment is still limited?&lt;/p&gt;

&lt;p&gt;Those aren't user questions. They're builder questions. And getting to the point where I'm asking builder questions is exactly what this pathway was designed to produce.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's next&lt;/strong&gt;&lt;br&gt;
I'm planning to build a basic Bitcoin wallet from scratch, not to ship a product, but because there's no better way to surface the real infrastructure decisions. Which APIs do you use before you have a self-hosted node? How do you construct and broadcast a transaction programmatically? How do you handle fee estimation in a way that doesn't get your transaction stuck?&lt;/p&gt;

&lt;p&gt;Starting with third-party APIs (Blockstream Esplora, Mempool.space) and eventually migrating toward running my own node is the path I'm planning. The goal isn't to build the best wallet,it's to understand what building a wallet actually requires.&lt;/p&gt;

&lt;p&gt;Beyond that, I want to start contributing to Bitcoin open source. That's the natural next step after understanding how the protocol works, moving from reading the code to actually touching it. I'm looking at projects like Bitcoin Core, the Rust Bitcoin ecosystem, and BDK (Bitcoin Dev Kit) as entry points. Open source contribution in Bitcoin isn't just about shipping code; it's about joining a community of people who are accountable to the protocol itself, where every change gets scrutinized, debated, and justified on technical merit. That kind of environment is exactly where the deepest learning happens.&lt;br&gt;
The roadmap is simple: build something real, break things, understand why they broke, and find a corner of the codebase where I can add value. Btrust Builders has given me the foundation. Now it's time to build on it.&lt;/p&gt;

&lt;p&gt;If you're a developer who's been Bitcoin-curious but hasn't found the right entry point, Mastering Bitcoin with a structured cohort around it is the clearest path I've come across. The book doesn't hide the complexity. But by the time you've worked through it properly, you realize the complexity is the point — it's what makes the system trustworthy.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ebube Miracle Ukpai is a participant in the Btrust Builders program, a Bitcoin developer education cohort.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>bitcoin</category>
      <category>bitdev</category>
    </item>
    <item>
      <title>Octant v2 Developer Tutorial: Building Yield-Donating Strategies</title>
      <dc:creator>Miracle656</dc:creator>
      <pubDate>Sat, 08 Nov 2025 21:56:32 +0000</pubDate>
      <link>https://dev.to/miracle656/octant-v2-developer-tutorial-building-yield-donating-strategies-6o1</link>
      <guid>https://dev.to/miracle656/octant-v2-developer-tutorial-building-yield-donating-strategies-6o1</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;🎯 What You'll Learn&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;By the end of this tutorial, you'll understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How Octant v2 transforms yield into sustainable public goods funding&lt;/li&gt;
&lt;li&gt;The architecture of yield-donating strategies&lt;/li&gt;
&lt;li&gt;How to build and deploy your own strategy&lt;/li&gt;
&lt;li&gt;Real-world examples with code walkthroughs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Part 1: Understanding Octant v2&lt;/strong&gt;&lt;br&gt;
The Problem Octant Solves&lt;br&gt;
Traditional funding models require either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Depleting treasuries (unsustainable)&lt;/li&gt;
&lt;li&gt;Taking from users (creates friction)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Octant's Innovation:&lt;/strong&gt; Use ONLY the yield, keep the principal forever!&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;The Flow&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;User deposits 10,000 USDC&lt;br&gt;
    ↓&lt;br&gt;
Strategy invests in Aave (earning 5% APY)&lt;br&gt;
    ↓&lt;br&gt;
After 1 year: 500 USDC yield generated&lt;br&gt;
    ↓&lt;br&gt;
User still has 10,000 USDC (can withdraw anytime)&lt;br&gt;
500 USDC goes to public goods as donation shares&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Key Concept: Donation Shares&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;User gets shares representing their PRINCIPAL&lt;/li&gt;
&lt;li&gt;Strategy mints NEW shares for YIELD&lt;/li&gt;
&lt;li&gt;Yield shares go to dragonRouter (donation address)&lt;/li&gt;
&lt;li&gt;This is like giving interest to charity while keeping your savings account balance!&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Part 2: Architecture Deep Dive&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Core Components&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. YieldDonatingTokenizedStrategy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The base contract you inherit from. Key functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// YOU IMPLEMENT THESE:
function _deployFunds(uint256 _amount) internal virtual;
function _freeFunds(uint256 _amount) internal virtual;
function _harvestAndReport() internal virtual returns (uint256);

// OCTANT HANDLES THESE:
function report() external onlyKeepers returns (uint256 profit, uint256 loss);
// ↑ This mints profit shares to dragonRouter automatically!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. The Report Mechanism&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// When keeper calls report():
1. Call _harvestAndReport() to get current totalAssets
2. Compare with previous totalAssets
3. If profit: mint shares to dragonRouter
4. If loss (optional): burn dragonRouter shares
5. Update accounting

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Factory Pattern&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract SkyCompounderStrategyFactory {
    function createStrategy(
        address _compounderVault,  // Yield source
        string memory _name,
        address _management,
        address _keeper,
        address _emergencyAdmin,
        address _donationAddress,  // Where yield goes!
        bool _enableBurning,
        address _tokenizedStrategyAddress
    ) external returns (address strategy);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Part 3: Building Your First Strategy&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Example: Aave v3 USDC Strategy&lt;/strong&gt;&lt;br&gt;
Let's build a strategy that deposits USDC into Aave and donates the yield!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Setup Your Interface&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.18;

interface IAaveV3Pool {
    function supply(
        address asset,
        uint256 amount,
        address onBehalfOf,
        uint16 referralCode
    ) external;

    function withdraw(
        address asset,
        uint256 amount,
        address to
    ) external returns (uint256);
}

interface IAToken {
    function balanceOf(address account) external view returns (uint256);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2: Implement Your Strategy&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {YieldDonatingTokenizedStrategy} from "./YieldDonatingTokenizedStrategy.sol";

contract AaveUsdcYieldDonating is YieldDonatingTokenizedStrategy {
    IAaveV3Pool public immutable aavePool;
    IAToken public immutable aUsdc;

    constructor(
        address _aavePool,
        address _aUsdc,
        address _asset,
        string memory _name,
        address _management,
        address _keeper,
        address _emergencyAdmin,
        address _donationAddress,
        bool _enableBurning,
        address _tokenizedStrategyAddress
    ) YieldDonatingTokenizedStrategy(
        _asset,
        _name,
        _management,
        _keeper,
        _emergencyAdmin,
        _donationAddress,
        _enableBurning,
        _tokenizedStrategyAddress
    ) {
        aavePool = IAaveV3Pool(_aavePool);
        aUsdc = IAToken(_aUsdc);

        // Approve Aave to spend our USDC
        ERC20(_asset).approve(_aavePool, type(uint256).max);
    }

    // REQUIRED: Deploy funds into Aave
    function _deployFunds(uint256 _amount) internal override {
        aavePool.supply(
            address(asset),
            _amount,
            address(this),
            0 // no referral code
        );
    }

    // REQUIRED: Withdraw funds from Aave
    function _freeFunds(uint256 _amount) internal override {
        aavePool.withdraw(
            address(asset),
            _amount,
            address(this)
        );
    }

    // REQUIRED: Calculate total assets
    function _harvestAndReport() internal override returns (uint256 _totalAssets) {
        // Assets in Aave (aUSDC represents our deposit + yield)
        uint256 aaveBalance = aUsdc.balanceOf(address(this));

        // Idle assets in strategy
        uint256 idleBalance = asset.balanceOf(address(this));

        // Total = deployed + idle
        _totalAssets = aaveBalance + idleBalance;

        // NOTE: Profit is calculated automatically!
        // If _totalAssets &amp;gt; lastTotalAssets, profit is minted to dragonRouter
    }

    // OPTIONAL: Set deposit limit based on Aave capacity
    function availableDepositLimit(address) public view override returns (uint256) {
        // Could check Aave's supply cap here
        return type(uint256).max; // unlimited for this example
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3: Understanding the Magic&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Initial State
deposit(10000 USDC) → user gets 10000 shares
totalAssets = 10000 USDC

// After 1 day (earned 10 USDC in Aave)
keeper.report() calls _harvestAndReport()
    → returns 10010 USDC
    → profit = 10010 - 10000 = 10 USDC
    → mint 10 shares to dragonRouter
    → user still has 10000 shares (unchanged!)
    → dragonRouter now has 10 shares

// User can still withdraw their full 10000 USDC
// dragonRouter has 10 shares worth 10 USDC to donate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Part 4: Testing Your Strategy&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Setup Test Environment&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// test/AaveStrategy.t.sol
pragma solidity 0.8.18;

import "forge-std/Test.sol";
import {AaveUsdcYieldDonating} from "../src/AaveStrategy.sol";

contract AaveStrategyTest is Test {
    AaveUsdcYieldDonating strategy;
    address user = address(0x1);
    address dragonRouter = address(0x2);

    function setUp() public {
        // Fork mainnet for real Aave interaction
        vm.createSelectFork(vm.envString("ETH_RPC_URL"));

        strategy = new AaveUsdcYieldDonating(
            0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2, // Aave V3 Pool
            0x98C23E9d8f34FEFb1B7BD6a91B7FF122F4e16F5c, // aUSDC
            0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48, // USDC
            "Aave USDC YieldDonating",
            address(this), // management
            address(this), // keeper
            address(this), // emergency admin
            dragonRouter,
            false, // no burning
            TOKENIZED_STRATEGY_ADDRESS
        );
    }

    function testYieldDonation() public {
        // 1. User deposits
        deal(USDC, user, 10000e6);
        vm.startPrank(user);
        IERC20(USDC).approve(address(strategy), 10000e6);
        strategy.deposit(10000e6, user);
        vm.stopPrank();

        // 2. Simulate time passing + yield accrual
        vm.warp(block.timestamp + 365 days);

        // 3. Keeper reports (this mints profit to dragonRouter)
        (uint256 profit, ) = strategy.report();

        // 4. Verify
        assertGt(profit, 0, "Should have generated profit");
        assertGt(strategy.balanceOf(dragonRouter), 0, "Dragon should have shares");
        assertEq(strategy.balanceOf(user), 10000e6, "User shares unchanged");
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Run Tests&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;forge test --match-contract AaveStrategyTest -vv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*&lt;em&gt;## Part 5: Deployment *&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create Deployment Script&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// script/DeployAaveStrategy.s.sol
pragma solidity 0.8.18;

import "forge-std/Script.sol";
import {AaveUsdcYieldDonating} from "../src/AaveStrategy.sol";

contract DeployAaveStrategy is Script {
    function run() external {
        uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
        address dragonRouter = vm.envAddress("DRAGON_ROUTER");

        vm.startBroadcast(deployerPrivateKey);

        AaveUsdcYieldDonating strategy = new AaveUsdcYieldDonating(
            0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2, // Aave V3
            0x98C23E9d8f34FEFb1B7BD6a91B7FF122F4e16F5c, // aUSDC
            0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48, // USDC
            "Aave USDC YieldDonating",
            msg.sender,
            msg.sender,
            msg.sender,
            dragonRouter,
            false,
            TOKENIZED_STRATEGY_ADDRESS
        );

        console.log("Strategy deployed at:", address(strategy));

        vm.stopBroadcast();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Deploy&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;forge script script/DeployAaveStrategy.s.sol \
    --rpc-url $ETH_RPC_URL \
    --broadcast \
    --verify \
    --etherscan-api-key $ETHERSCAN_API_KEY
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Part 6: Interacting with Your Strategy&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Using ethers.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { ethers } from 'ethers';

const provider = new ethers.providers.JsonRpcProvider(RPC_URL);
const strategy = new ethers.Contract(STRATEGY_ADDRESS, STRATEGY_ABI, provider);

// 1. Check strategy info
const totalAssets = await strategy.totalAssets();
const dragonRouter = await strategy.dragonRouter();
const pricePerShare = await strategy.pricePerShare();

console.log(`TVL: ${ethers.utils.formatUnits(totalAssets, 6)} USDC`);

// 2. Deposit (as user)
const signer = new ethers.Wallet(PRIVATE_KEY, provider);
const strategyWithSigner = strategy.connect(signer);

const usdc = new ethers.Contract(USDC_ADDRESS, ERC20_ABI, signer);
await usdc.approve(STRATEGY_ADDRESS, ethers.utils.parseUnits("1000", 6));
await strategyWithSigner.deposit(ethers.utils.parseUnits("1000", 6), signer.address);

// 3. Report yield (as keeper)
const tx = await strategyWithSigner.report();
const receipt = await tx.wait();
console.log(`Yield reported! Gas used: ${receipt.gasUsed}`);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  *&lt;em&gt;Part 7: Advanced Patterns *&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Multi-Protocol Strategy&lt;/strong&gt;&lt;br&gt;
Deploy across multiple yield sources:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract MultiProtocolStrategy is YieldDonatingTokenizedStrategy {
    IAaveV3Pool public aave;
    ICompound public compound;

    // Split deposits 50/50
    function _deployFunds(uint256 _amount) internal override {
        uint256 half = _amount / 2;
        aave.supply(address(asset), half, address(this), 0);
        compound.supply(address(asset), half);
    }

    function _harvestAndReport() internal override returns (uint256) {
        return aave.balanceOf(address(this)) 
             + compound.balanceOf(address(this))
             + asset.balanceOf(address(this));
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Auto-Rebalancing Strategy&lt;/strong&gt;&lt;br&gt;
Move funds to highest yield:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function _tend(uint256 _totalIdle) internal override {
    uint256 aaveApy = getAaveApy();
    uint256 compoundApy = getCompoundApy();

    if (aaveApy &amp;gt; compoundApy * 101 / 100) { // 1% threshold
        // Move from Compound to Aave
        uint256 compoundBalance = compound.balanceOf(address(this));
        compound.withdraw(compoundBalance);
        aave.supply(address(asset), compoundBalance, address(this), 0);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  *&lt;em&gt;Part 8: Common Pitfalls *&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;❌ Mistake 1: Forgetting Idle Assets&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// WRONG
function _harvestAndReport() internal override returns (uint256) {
    return aave.balanceOf(address(this)); // Missing idle!
}

// CORRECT
function _harvestAndReport() internal override returns (uint256) {
    return aave.balanceOf(address(this)) 
         + asset.balanceOf(address(this)); // Include idle
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;❌ Mistake 2: Not Approving Tokens&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Add in constructor:
ERC20(_asset).approve(_yieldSource, type(uint256).max);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;❌ Mistake 3: Wrong Share Accounting&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Octant handles share minting automatically in report()
// DON'T manually mint shares for profit!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Part 9: Resources &amp;amp; Next Steps&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Documentation&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Octant Docs: &lt;a href="https://docs.v2.octant.build" rel="noopener noreferrer"&gt;https://docs.v2.octant.build&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Yearn v3 (similar architecture): &lt;a href="https://docs.yearn.fi/developers/v3/overview" rel="noopener noreferrer"&gt;https://docs.yearn.fi/developers/v3/overview&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example Strategies&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sky Compounder: See SkyCompounderStrategy.sol&lt;/li&gt;
&lt;li&gt;Lido Strategy: See LidoStrategy.sol&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Community&lt;/p&gt;

&lt;p&gt;Discord: [&lt;a href="https://discord.gg/octant" rel="noopener noreferrer"&gt;https://discord.gg/octant&lt;/a&gt;]&lt;br&gt;
GitHub: &lt;a href="https://github.com/golemfoundation/octant-v2-core" rel="noopener noreferrer"&gt;https://github.com/golemfoundation/octant-v2-core&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Challenge Yourself&lt;br&gt;
Try building strategies for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Morpho Blue&lt;/li&gt;
&lt;li&gt;Spark Protocol&lt;/li&gt;
&lt;li&gt;Compound v3&lt;/li&gt;
&lt;li&gt;Uniswap v4 hooks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Summary Checklist&lt;/strong&gt;&lt;br&gt;
✅ Understand yield donation concept&lt;br&gt;
✅ Know the 3 required functions to implement&lt;br&gt;
✅ Can test strategies with Foundry&lt;br&gt;
✅ Can deploy strategies to mainnet&lt;br&gt;
✅ Understand profit minting mechanism&lt;br&gt;
✅ Know common pitfalls to avoid&lt;br&gt;
*&lt;em&gt;You're now ready to build production-grade yield-donating strategies for Octant v2!&lt;br&gt;
*&lt;/em&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
    </item>
  </channel>
</rss>
