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.
| Contract | ARC-32 | ARC-56 |
|---|---|---|
| dualSTAKE Contract — one instance per staking pool (e.g. coopALGO) | contract.arc32.json | contract.arc56.json |
| Registry Contract — global directory of dualSTAKE pools | registry.arc32.json | registry.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
| Method | Description |
|---|---|
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.
| Method | Role | Description |
|---|---|---|
configure(...) / configure2(...) | admin / fee admin | Bootstrap global storage and mint the LST. |
queue_update_fees(uint64,uint64) | fee admin | Schedule a fee change (±2.5% max delta). |
reset_update_fees() | fee admin | Cancel a scheduled fee update. |
update_max_balance(uint64) | fee admin | Update the max ALGO stake cap. |
withdraw_platform_fees(uint64) | fee admin | Withdraw accrued platform fees. |
withdraw_node_runner_fees(uint64) | fee admin / node runner | Withdraw node runner fees to the node runner address. |
withdraw_ds_surplus() | fee admin | Sweep LST accidentally sent to the escrow. |
keyreg_online(...) / keyreg_offline() | fee admin / node runner | Manage consensus key registration. |
change_admin_1(address) / change_admin_2() | admin / new admin | Two-step admin handover. |
change_feeaddr(address) | admin / fee admin | Change the fee admin address. |
change_noderunner(address) | fee admin / node runner | Change the node runner address (fees must be withdrawn first). |
queue_upgrade(byte[]) | admin | Stage an upgrade (1-week vesting). |
reset_upgrade() | admin / fee admin | Clear a staged upgrade. |
admin_unprotest_stake(address) | fee admin | Return a user's protesting stake after a cancelled upgrade. |
dissolve_protesting_stake(address) | fee admin | Dissolve a user's protesting stake to execute an upgrade. |
verify_nfdomains(...) | fee admin | Verify 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.
| Method | Description |
|---|---|
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. |