Contract ABI

The dualSTAKE protocol is made up of two on-chain smart contracts. Their application specifications are published here in both ARC-32 and ARC-56 formats. Use these specs to generate typed clients or to decode application calls, events, and state.

ContractARC-32ARC-56
dualSTAKE Contract — one instance per staking pool (e.g. coopALGO)contract.arc32.jsoncontract.arc56.json
Registry Contract — global directory of dualSTAKE poolsregistry.arc32.jsonregistry.arc56.json

The ARC-56 specs are the richer, canonical source: they include struct definitions, ARC-28 events, and global/local state schema. The ARC-32 specs are provided for tooling that has not yet migrated to ARC-56.

For a ready-made TypeScript client generated from these specs, see the Typescript SDK.

dualSTAKE Contract

One instance is deployed per staking pool. It custodies staked ALGO, mints and redeems the liquid staking token (LST), swaps accrued ASA staking rewards, manages key registration, and enforces the fee and upgrade rules described throughout these docs.

Public methods

MethodDescription
mint()Mint dualSTAKE LST. Preceding group payment in ALGO (and ASA when required).
redeem()Redeem dualSTAKE LST back to ALGO + ASA.
get_rate()Current exchange rate as a uint64 (see Exchange Rate).
get_rate_and_balances()Rate plus escrow ALGO and ASA balances.
get_contract_listing(address)Full ContractListing struct for the pool.
get_need_swap()Whether the contract needs to swap accrued rewards.
swap_or_fail()Force a reward swap, or fail.
protest_stake()Lock LST as an upgrade protest.
unprotest_stake()Revoke your own protesting stake.
nullun()No-op used to raise the opcode budget.

Privileged methods

See Roles for who may call each.

MethodRoleDescription
configure(...) / configure2(...)admin / fee adminBootstrap global storage and mint the LST.
queue_update_fees(uint64,uint64)fee adminSchedule a fee change (±2.5% max delta).
reset_update_fees()fee adminCancel a scheduled fee update.
update_max_balance(uint64)fee adminUpdate the max ALGO stake cap.
withdraw_platform_fees(uint64)fee adminWithdraw accrued platform fees.
withdraw_node_runner_fees(uint64)fee admin / node runnerWithdraw node runner fees to the node runner address.
withdraw_ds_surplus()fee adminSweep LST accidentally sent to the escrow.
keyreg_online(...) / keyreg_offline()fee admin / node runnerManage consensus key registration.
change_admin_1(address) / change_admin_2()admin / new adminTwo-step admin handover.
change_feeaddr(address)admin / fee adminChange the fee admin address.
change_noderunner(address)fee admin / node runnerChange the node runner address (fees must be withdrawn first).
queue_upgrade(byte[])adminStage an upgrade (1-week vesting).
reset_upgrade()admin / fee adminClear a staged upgrade.
admin_unprotest_stake(address)fee adminReturn a user's protesting stake after a cancelled upgrade.
dissolve_protesting_stake(address)fee adminDissolve a user's protesting stake to execute an upgrade.
verify_nfdomains(...)fee adminVerify NFDomains association.

Registry Contract

A single global instance acts as the on-chain directory of every dualSTAKE pool. It maps a staked ASA to its dualSTAKE app and LST, records pool listings, and provides contract-to-contract lookups.

MethodDescription
assign_contract()Register a dualSTAKE contract with the registry.
unassign_contract(byte[])Remove a dualSTAKE contract registration.
get_asa_dualstake_app_id(uint64)C2C lookup: staked ASA ID → dualSTAKE app ID (e.g. COOP → coopALGO app).
get_asa_dualstake_asset_id(uint64)C2C lookup: staked ASA ID → dualSTAKE LST ASA ID (e.g. COOP → coopALGO).
log_dualstake_listings(uint64[])Log the ContractListing for a set of dualSTAKE apps.
vanity_configure(uint64,byte[],byte[],byte[])Mint a dualSTAKE LST with a vanity ASA ID (% 1000 == 0).
withdraw_algo(uint64)Withdraw available ALGO from the registry escrow.
change_admin_1(address) / change_admin_2()Two-step admin handover.