Asynchronous Reward Compounding
How reward claiming and compounding work when they can't happen atomically with a strategy action.
In sophisticated DeFi strategies, yield is often composed of Synchronous Yield (intrinsic interest accrual) and Asynchronous Rewards (external incentives). For an Atomist curating a Fusion Vault, the temporal gap between earning a reward and compounding it into the vault's totalAssets() creates a dynamic where the share price may temporarily deviate from the strategy's "true" economic value.
This gap results in one of two effects depending on TVL fluctuations: Dilution or Concentration.
The Compounding Gap
Synchronous Accrual
Base lending protocols (like Aave or Morpho) usually provide synchronous yield. When a Fusion Vault calls updateMarketsBalances(), the vault's share price immediately reflects the interest earned or the costs incurred (e.g., borrowing fees).
Asynchronous Accrual
Many incentive programs (e.g., $ARB, $OP, or $MORPHO) accrue rewards on external distributor contracts. These assets are "invisible" to the vault's exchange rate until the Atomist:
- Claims tokens via the
RewardsClaimManager. - Converts them to the underlying asset via the
UniversalTokenSwapper. - Re-deposits them, effectively increasing
totalAssets().
Temporal Effects: Inflow vs. Outflow
Because the share price only accounts for assets currently tracked within the vault's storage, the value of pending (unclaimed) rewards exists "off-balance-sheet."
1. Reward Dilution (Capital Inflow)
If a large deposit occurs after a reward has been earned but before it is compounded, the new capital receives a pro-rata share of rewards it did not help earn. This is particularly noticeable in leveraged strategies where the vault has already realized the synchronous cost of the leverage (borrowing fees) but has not yet realized the asynchronous upside (incentives).
2. Reward Concentration (Capital Outflow)
Conversely, if a significant portion of the TVL is withdrawn before the compounding point, the remaining shareholders benefit from "positive dilution." The rewards earned by the total capital are now distributed among a smaller pool of shares, making the compounding event accretive to the remaining users.
Technical Example: 7-Day Compounding Cycle
Consider a Fusion Vault utilizing a leveraged supply strategy.
Initial State:
- TVL: 1,000,000 USDC
- Total Supply: 1,000,000 shares (Price: 1.0000)
- Strategy: 3% APY borrow cost to farm a reward token yielding 5% APY.
Accrual Period (7 Days):
The vault maintains the position for one week.
Synchronous Cost (C):
Asynchronous Reward (R):
State at Day 7 (Pre-Compounding):
The borrow cost is realized via updateMarketsBalances(), but the reward is pending.
- Total Assets: 999,424.66 USDC
- Share Price: 0.99942
Scenario A: Large Inflow (Dilution)
A user deposits 4,000,000 USDC right before compounding.
- New Total Supply: shares.
- Post-Compounding Price: After adding the 958.90 USDC reward:
Note: The original users lose nearly all their net yield to the new capital inflow.
Scenario B: Large Outflow (Concentration)
Users withdraw 500,000 USDC right before compounding.
- New Total Supply: 500,000 shares remaining.
- Post-Compounding Price: After adding the 958.90 USDC reward to the remaining 499,424.66 USDC assets:
Note: The remaining users receive a higher share price because they capture the rewards earned by the capital that just exited.
Strategic Management for Atomists
Atomists should manage the compounding gap to ensure fairness and strategy stability.
1. Compounding Frequency
Increasing the frequency of reward realization (e.g., daily instead of weekly) minimizes the window for both dilution and concentration, keeping the share price closer to the strategy's fair value.
If rewards can be claimed at specific time intervals, the compounding period should correspond to these intervals. Otherwise, fluctuations in the share price can occur, which could be exploited through timed depositing and withdrawing, leading to yield leakage from the vault.
2. Onboarding Contributions
The FeeManager can be used to set a Onboarding Contribution. This fee acts as an "entry contribution" that can offset the dilution of existing shareholders, effectively pricing in the value of pending rewards for new participants.
3. Scaling and Velocity
Atomists should monitor TVL Velocity. Strategies with high asynchronous components should be scaled carefully. Sudden spikes in TVL can be managed using setTotalSupplyCap(), allowing the vault to grow in stages that align with compounding cycles.
4. Vesting Claimed Rewards
Compounding a claimed reward straight into the vault adds it to totalAssets() in one block, so the share price jumps at every claim. A depositor who enters just before a claim and exits right after captures part of a reward the vault earned over the whole claim interval. The RewardsClaimManager removes the jump: it releases claimed rewards into totalAssets() linearly over a vesting period the Atomist sets.
How vesting works
- The vault counts
RewardsClaimManager.balanceOf()intotalAssets(). With a vesting time of 0, that is the manager's whole balance of the vault's underlying asset. With a vesting time above 0, it is only the part vested so far. updateBalance()moves the vested part to the vault and starts a new linear vest of everything the manager still holds, over the full vesting time.- Only the vault's underlying asset vests. Other tokens in the manager are not counted in
totalAssets()until they are converted to the underlying asset and sent back to the manager. transferVestedTokensToVault()is public. It moves the vested part to the vault without changingtotalAssets().
Roles
| Function | Role | Who holds it |
|---|---|---|
setupVestingTime(seconds) | ATOMIST_ROLE (100) | Atomist |
claimRewards(...) | CLAIM_REWARDS_ROLE (600) | Alpha |
transfer(token, to, amount) | TRANSFER_REWARDS_ROLE (700) | Alpha or a conversion account; cannot move the underlying asset |
updateBalance() | UPDATE_REWARDS_BALANCE_ROLE (1100) | Alpha |
The Atomist is the admin of roles 600, 700 and 1100 and grants them in the vault's IporFusionAccessManager.
Setup
- Set the vesting time with
setupVestingTime. Match it to the claim interval: if rewards are claimed every 36 hours, vest over about 36 to 48 hours. A longer period gives a smoother share price but delays the reward, and depositors who exit leave the unvested part to those who stay. - Grant
TRANSFER_REWARDS_ROLEandUPDATE_REWARDS_BALANCE_ROLEto the Alpha (or the account that converts rewards).
Each claim cycle
- Claim through
RewardsClaimManager.claimRewards. Claim fuses send the claimed tokens to the manager. ForMerklClaimFuse, keep the reward token out of thedoNotTransferToRewardManagerlist; a token on that list stays in the vault and is compounded at once. For wrapped Merkl tokens useMerklClaimWrapperFuse(see Checks). - If the reward token is not the underlying asset,
transferit to the conversion account, convert it to the underlying asset, and send the proceeds back to theRewardsClaimManageraddress. - Call
updateBalance(). The new balance starts vesting.
Checks
getVestingData()returnsvestingTime,updateBalanceTimestamp(0 means vesting never started),transferredTokensandlastUpdateBalance.setupVestingTimecan revert in the middle of a vest when the new time would cut the already-released amount. CallupdateBalance()first, then change the time.MerklClaimFuseforwards the balance change of the token named in the claim. Some Merkl reward tokens are wrappers that unwrap on transfer and pay out a different token (for example a wrapped Aave aToken that delivers the aToken itself). WithMerklClaimFusethe claimed token's balance does not change and nothing reaches the manager. UseMerklClaimWrapperFusefor these tokens: itsclaimtakes the list of tokens that actually arrive (receivedTokens), measures their balance change and forwards it to the manager. Each received token must be granted as a substrate-as-asset on the fuse'sMARKET_ID, and the fuse must be added to the manager withaddRewardFuses.- Rewards held in the conversion account are outside the vault and are not counted in
totalAssets()until they come back to the manager. Keep the round trip short.