We’ve been testing various models for distribution of rewards to DeFi pools. This policy is still under discussion and may change without notice until finalized.
Be noted that holding pure fragAsset
ensures that the owner can claim rewards directly by executing a transaction.
This guide is for handling rewards accrued from wfragAsset
.
Process
By design, Fragmetric’s restaking protocol tracks fragAsset (Token-2022) balances fully and accurately on-chain to account for each user’s portion of rewards.
However, wfragAsset
is a legacy SPL token and does not support the same tracking capabilities.
Fragmetric uses the following approach for tracking wfragAsset
contributions:
1. Register Token Account
Register specific wfragAsset
token accounts to be tracked on-chain. A dedicated reward account is created per registered token account.
- wfragAsset Holder: An alias for token accounts owned by a DeFi protocol that hold user
wfragAsset
deposits.
2. Delegate Reward Account
Initially, the created reward accounts belong to the Fragmetric Fund Manager (governance).
The authority to claim rewards will be transferred to the appropriate governance address of the DeFi protocol.
3. Track Token Accounts
Fund operations — which are executed regularly for each fund (fragSOL
, fragJTO
, fragBTC
) — will track registered token accounts and update their contribution share in the reward system.
4. Claim and Distribute Rewards
Once delegated, the DeFi protocol’s representative can claim settled rewards using a dedicated on-chain instruction or via SDK/CLI tools.
Claimed rewards can then be redistributed to users according to the protocol’s internal emission policy.
In brief, this process emulates fragAsset
-based reward tracking with reduced accuracy and flexibility, tailored for protocols using wfragAsset
.
It is activated and maintained through consensus between Fragmetric governance and the participating DeFi protocol.
Claim Instruction
You can call the user_claim_reward
instruction of the restaking program
either on-chain or off-chain.
The Anchor IDL is embedded in the @fragmetric-labs/sdk package.
Alternatively, you can download the latest IDL from the restaking program account on Solana Explorer.
Claim via SDK
The following CLI session demonstrates reward resolution and claiming.
The CLI and TypeScript SDK interfaces are functionally equivalent. For building an unsigned transaction, you can omit keypairs. Also, for multisig transaction building, you can manually configure the nonce account via the SDK (this is not available via CLI).
# Connect with your keypair
$ pnpx @fragmetric-labs/sdk@latest connect --url devnet --keypairs ./keypairs/wallet.json
# Initialize user context for your wfragAsset token account
> user = restaking.fragSOL.user('YOUR_WFRAG_ASSET_TOKEN_ACCOUNT_ADDRESS')
# Resolve current reward state
> user.reward.resolve()
{
user: '91zBeWL8kHBaMtaVrHwWsck1UacDKvje82QQ3HE2k8mJ',
delegate: null,
receiptTokenMint: 'FRAGSEthVFL7fdqM8hxfxkfCZzUvmg21cqPJVvC1qdbo',
basePool: {
contribution: 82_615_701_067_571_732_800n,
updatedSlot: 380_567_800n,
tokenAllocatedAmount: {
totalAmount: 9_280_215_900n,
records: [ { amount: 9_280_215_900n, contributionAccrualRate: 1 } ]
},
settlements: [
{
reward: {
id: 1,
name: 'SWTCH',
description: 'Switchboard Token',
claimable: false,
mint: 'FSWSBMV5EB7J8JdafNBLZpfSCLiFwpMCqod2RpkU4RNn',
program: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
decimals: 9
},
settledSlot: 374_372_372n,
settledContribution: 76_940_980_900_143_937_700n,
settledAmount: 1_909_701_124_839_547_123n,
claimedAmount: 0n
}
]
},
...
}
# Sync reward pool state (optional, it updates by fund operation)
> user.reward.updatePools.execute()
◐ Signed 4foCqwkzk5ePJWBCdVx3dXQHXw7HFbYeurjj4UJDmToDFCGFtWaqjrRHN7ySQhB7eCvL6q9JSSZatxyycTwiYi1P
✔ Confirmed manually triggers contribution synchronization for the user reward pools {
succeeded: true,
slot: 380_773_521n,
args: null,
events: {
unknown: [],
userUpdatedRewardPool: {
receiptTokenMint: 'FRAGSEthVFL7fdqM8hxfxkfCZzUvmg21cqPJVvC1qdbo',
updatedUserRewardAccounts: [ 'CCmAQhBS1FxU5TEbtmMCXZez1skdtZ2RfW5KR7xUjDFE' ]
}
}
}
# Claim a reward
> user.reward.claim.execute({ mint: 'REWARD_MINT_ADDRESS', recipient: 'RECIPIENT_ADDRESS (NOT TOKEN ACCOUNT)', amount: 1n })
◐ Signed 4B1k14d3aabmbGcJ7w4U9J5JQVa98c51DFsKMpZAbnqdn5m4UZVwtjHnVZygadXJ1Wm9AwHuvmsiWsp5XM2RsvCj
✔ Confirmed claim rewards {
succeeded: true,
slot: 339_924_620n,
args: {
delegate: null,
isBonus: false,
mint: 'ZEUS1aR7aX8DFFJf5QjWj2ftDDdNTroMNGo8YoQm3Gq',
amount: 1n,
recipient: 'D5zDEBSiA497dge26i4vwHsLk75exUghMoFDc8mBeJDu'
},
events: {
unknown: [],
userClaimedReward: {
receiptTokenMint: 'FRAGB4KZGLMy3wH1nBajP3Q17MHnecEvTPT6wb4pX5MB',
user: '91zBeWL8kHBaMtaVrHwWsck1UacDKvje82QQ3HE2k8mJ',
rewardTokenMint: 'ZEUS1aR7aX8DFFJf5QjWj2ftDDdNTroMNGo8YoQm3Gq',
destinationRewardTokenAccount: 'CGLyDs5DzqyB3WW2Nj9rD9Lp1Po5fLjetXW5RKTbaWTA',
destinationRewardTokenAccountOwner: 'D5zDEBSiA497dge26i4vwHsLk75exUghMoFDc8mBeJDu',
updatedRewardAccount: '2tfQHwAKpj7h6tEVbbWysKVMY9pCAaLpGcnozFFLng8Y',
updatedUserRewardAccount: '3VwayPkYSkPM7qHcExiLJ59xp5S19UcyLXcDxRVmC7Tp',
claimedRewardTokenAmount: 1n,
totalClaimedRewardTokenAmount: 380_073n
}
}
}