Vetra stablecoin — verifying USD reserves in real time with Chainlink Functions on Polygon

Ustym Kushnir
Ustym Kushnir
··10 min read

Behind the Vetra USD-backed stablecoin on Polygon PoS. Chainlink Functions verifies fiat reserves in real time, pausable ERC-20 with role-based access, on-chain audit trail, deployment checklist and incident response plan.

A stablecoin is only as trustworthy as the mechanism that proves the reserves are actually there. Terra collapsed. USDT gets audited annually and everyone still asks. The design goal of Vetra was: anyone, at any time, can verify the current USD backing on-chain.

The mechanism#

Chainlink Functions is a decentralized off-chain compute layer that lets an on-chain contract request data from a real API and receive it back on-chain, signed by a decentralized oracle network. The Vetra contract calls Chainlink Functions on a schedule (every 4 hours) to fetch the current bank balance from the reserves account API, and writes the result to a public on-chain totalReserves variable.

Anyone can read totalReserves. Anyone can compare it to totalSupply on the ERC-20. If they diverge, the contract auto-pauses transfers until an admin intervenes.

This is not a full audit. A full audit still requires a human accountant reconciling bank statements. But it eliminates the "trust me bro" gap between quarterly audits.

The contract shape#

  • ERC-20 with 6 decimals (matching USDC/USDT conventions).
  • Pausable — role-restricted to a multisig, not a single EOA.
  • AccessControl — minter, pauser, oracle-updater roles are separate.
  • Chainlink Functions consumer that updates totalReserves on schedule.
  • Auto-pause if totalReserves < totalSupply for 2 consecutive updates.

What could still go wrong#

  • The Chainlink Functions call is decentralized-ish. A collusion attack on the oracle nodes could report a fake balance. Chainlink's economic security makes this expensive but not impossible.
  • The bank API itself could be compromised. The best-in-class solution here is dual-source: two independent bank APIs must agree before the contract accepts the update. Vetra runs single-source today because the reserves are in one bank; when they split across two, dual-source ships.
  • The multisig holding the pauser role is 3-of-5 with hardware wallets across two geographies. Not perfect, materially better than a hot-wallet EOA.

Why Polygon PoS, not Ethereum L1 or a rollup#

Ethereum L1 is too expensive for retail stablecoin transfers. Optimistic rollups (Arbitrum, Optimism) have withdrawal delays that scare stablecoin holders. zk-rollups (zkSync, Starknet) are still catching up on tooling and gas subsidies. Polygon PoS is EVM-compatible, cheap, has real users, and settles fast — a pragmatic choice for a retail-facing token.

The trade-off is that Polygon PoS is not as secure as Ethereum L1. Vetra mitigates this by keeping reserves in a real bank (not a smart-contract vault), so the chain compromise scenario costs the attacker the ability to move Vetra between wallets, not the ability to drain the reserves.

Deployment checklist#

Every deployment step is written down, signed off, and executed in front of two people. No exceptions.

  • Contracts compiled with a pinned Solidity version (0.8.24). Verified against Hardhat + Foundry tests.
  • Deployed first to Polygon Amoy (testnet). 2-week client-side smoke test with fake reserves.
  • Contracts verified on Polygonscan against the exact source hash.
  • Multisig deployed and initialized with the 3-of-5 signer set.
  • Roles granted to the multisig, revoked from the deployer EOA. The deployer EOA is now powerless.
  • Chainlink Functions subscription funded with enough LINK for 6 months of updates.
  • Mainnet deployment executed by the multisig, in a video call, with a written pre-flight signed by both engineers.

Every one of those steps has failed in a real project somewhere. Writing the checklist is the whole point.

The incident response plan#

If totalReserves < totalSupply triggers an auto-pause, the plan is:

  • Auto-pause fires. Transfers stop within one block.
  • On-call engineer paged. Multisig signers alerted.
  • Public status page updated (pre-drafted).
  • Bank reconciliation started. Chainlink logs reviewed.
  • Root cause identified: (a) real reserve shortfall → resolve with the bank before unpausing, (b) Chainlink false reading → verify with a second data source, unpause after 2 consecutive good readings, (c) contract bug → coordinated upgrade via the multisig.
  • Post-mortem published within 72 hours regardless of cause.

Nobody wants to run this plan. Everybody should have one anyway.

The client owns#

The contract source, the deployment scripts, the Chainlink subscription, the multisig, the reserves account, and the operational runbook. My involvement post-launch is on-demand consulting for incidents and upgrades.

Share this article

Related case studies

Want your project written up like this?

See servicesContact