LibChain Docs Lib Testnet

Concepts

Wrapped tLIB (WtLIB)

WtLIB is an ERC-20 backed 1:1 by tLIB held in its contract. Wrap with deposit(), unwrap with withdraw(). Source is verified on Lib Explorer.

Native tLIB isn't an ERC-20 token, so contracts that expect one (DEX pools, vaults, token lists) can't hold it directly. WtLIB fixes that, the same way WETH does on Ethereum: send tLIB in, get the same amount of WtLIB out, and burn WtLIB to get tLIB back.

Address0x87052f1f17b2b4054b014e93e53d6ce6dc912bda
lib1suzj78chk26q2jcpf6f720tvumwfz276ynschv
Name / symbolWrapped tLIB / WtLIB
Decimals18
SourceVerified on Lib Explorer · Solidity 0.8.28, optimised, EVM Cancun
DeployedBlock 264

#Wrap and unwrap

The easiest way is the Wrap page in LibChain Hub. From code:

Terminal
# wrap 1 tLIB
cast send 0x87052f1f17b2b4054b014e93e53d6ce6dc912bda "deposit()" --value 1ether \
  --rpc-url https://rpc-testnet.libchain.tech --private-key $PRIVATE_KEY

# unwrap 1 WtLIB
cast send 0x87052f1f17b2b4054b014e93e53d6ce6dc912bda "withdraw(uint256)" 1000000000000000000 \
  --rpc-url https://rpc-testnet.libchain.tech --private-key $PRIVATE_KEY

# balance
cast call 0x87052f1f17b2b4054b014e93e53d6ce6dc912bda "balanceOf(address)(uint256)" 0xYourAddress --rpc-url https://rpc-testnet.libchain.tech
TypeScript
import { parseAbi, parseEther } from 'viem'

const WTLIB = '0x87052f1f17b2b4054b014e93e53d6ce6dc912bda'
const abi = parseAbi([
  'function deposit() payable',
  'function withdraw(uint256 amount)',
  'function balanceOf(address) view returns (uint256)',
])

await wallet.writeContract({ address: WTLIB, abi, functionName: 'deposit', value: parseEther('1') })
await wallet.writeContract({ address: WTLIB, abi, functionName: 'withdraw', args: [parseEther('1')] })
TypeScript
import { Contract, parseEther } from 'ethers'

const wtlib = new Contract('0x87052f1f17b2b4054b014e93e53d6ce6dc912bda', [
  'function deposit() payable',
  'function withdraw(uint256 amount)',
  'function balanceOf(address) view returns (uint256)',
], signer)

await (await wtlib.deposit({ value: parseEther('1') })).wait()
await (await wtlib.withdraw(parseEther('1'))).wait()

Sending tLIB straight to the contract also wraps it: receive() calls the same deposit logic.

#Guarantees

  • Always backed. The contract keeps address(this).balance ≥ totalSupply. WtLIB is only minted by a matching deposit.
  • Always redeemable. The admin can pause deposits and transfers, but never withdrawals. Holders can always get their tLIB back.
  • Limited admin. The admin can pause, recover other tokens sent by mistake, sweep only tLIB in excess of the supply, and hand over the role in two steps.

The current backing is shown live on the Hub's Wrap page. The full interface is in Contracts.

Updated 5 November 2026LibChain Docs · Lib Testnet