Stake Pool Shares
Users can stake pool shares to an ERC20 Staking contract to earn rewards. The staking conract is specific to the pool that was staked to and is created by ThirdWeb.
Addresses you’ll need per pool
staking
: Thirdweb ERC20 staking (stakes vault shares)rewardToken
: ERC20 paid bystaking
The following code example is in typescript. These smart contract integrations can be generalized to any codebase.
Minimal ABIs
// Thirdweb StakingERC20 (stake/withdraw/claimRewards/getStakeInfo)
export const stakingErc20Abi = [
{ type:'function', name:'stake', stateMutability:'nonpayable', inputs:[{type:'uint256','name':'amount'}], outputs:[] },
{ type:'function', name:'withdraw', stateMutability:'nonpayable', inputs:[{type:'uint256','name':'amount'}], outputs:[] },
{ type:'function', name:'claimRewards', stateMutability:'nonpayable', inputs:[], outputs:[] },
// returns (stakedAmount, claimableRewards)
{ type:'function', name:'getStakeInfo', stateMutability:'view', inputs:[{type:'address','name':'staker'}], outputs:[{type:'uint256'},{type:'uint256'}]},
] as const;
STAKE (approve shares → staking.stake)
User stakes vault shares (the ERC20 share token is the same vault
address).
export async function stakeShares({
client, account, vault, staking, sharesStr, vaultShareDecimals,
}: {
client:any; account:`0x${string}`; vault:`0x${string}`; staking:`0x${string}`;
sharesStr:string; vaultShareDecimals:number;
}) {
const shares = parseUnits(sharesStr, vaultShareDecimals);
// approve staking to spend your shares
const current = await client.readContract({
address: vault, abi: erc20Abi, functionName: 'allowance',
args: [account, staking],
}) as bigint;
if (current < shares) {
await client.writeContract({
address: vault, abi: erc20Abi, functionName: 'approve',
args: [staking, shares],
});
}
// stake
await client.writeContract({
address: staking, abi: stakingErc20Abi, functionName: 'stake', args: [shares],
});
}
READS for UI: balances
Staked in Thirdweb staking (shares held on contract for user)
export async function readStakingBalances({ client, staking, vault, user }:{
client:any; staking:`0x${string}`; vault:`0x${string}`; user:`0x${string}`;
}) {
const [stakedShares, claimable] = await client.readContract({
address: staking, abi: stakingErc20Abi, functionName: 'getStakeInfo', args: [user],
}) as readonly [bigint, bigint];
const stakedAssets = await client.readContract({
address: vault, abi: erc4626Abi, functionName: 'convertToAssets', args: [stakedShares],
}) as bigint;
return { stakedShares, stakedAssets, claimableRewards: claimable };
}
Last updated