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 by staking

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