Skip to content

📑 PR: feat(zest-repay-primitive): add Zest V2 repay primitive#607

Closed
TheBigMacBTC wants to merge 1 commit into
mainfrom
feat-zest-repay-primitive
Closed

📑 PR: feat(zest-repay-primitive): add Zest V2 repay primitive#607
TheBigMacBTC wants to merge 1 commit into
mainfrom
feat-zest-repay-primitive

Conversation

@TheBigMacBTC
Copy link
Copy Markdown
Contributor

Skill Submission

Skill name: zest-repay-primitive
Category: Infrastructure
HODLMM integration? No — Zest V2 protocol primitive; not HODLMM-related.

What it does

Repays a selected Zest V2 debt asset against an existing V2 debt position on Stacks mainnet. Single-asset repay via SP1A27KFY4XERQCCRCARCYD1CC5N7M6688BSYADJ7.v0-4-market.repay(ft, amount, on-behalf-of). One operator-selected amount (or --max for full repay), one transaction, one proof.

Mirrors the architectural pattern of #574 (zest-asset-deposit-primitive) and #572 (zest-borrow-asset-primitive):

  • Imports @stacks/transactions, uses makeContractCall + broadcastTransaction, polls Hiro for tx_status: success
  • PostConditionMode.Deny with wallet-side willSendLte(amount) postcondition
  • Reads live state (market canonicality, repay ABI, position, debt index/next-index, wallet balance, gas, mempool depth) before planning or broadcasting
  • JSON envelope: { status, action, data, error }
  • Confirmation token: REPAY
  • Primitive-only scope: no controller logic, no collateral withdraw, no swap, no oracle refresh (V2 repay path does not require Pyth)

Designed to be composed via Bun.spawn by leverage / unwind controllers — see the architectural-gap discussion on #606 (review).

Commands

Command Purpose
doctor Verify Zest V2 contracts are canonical, repay ABI exists, wallet has gas, no pending tx
status Read current debt state (scaledDebt, current/next debt index, wallet balance of repay asset)
plan Preview repay args + postconditions + proof obligations (read-only)
run Broadcast confirmed repay, poll for tx_status: success, return proof JSON

Flags

  • --wallet <stacks-address> (required)
  • --repay-asset <symbol> — STX / sBTC / stSTX / USDC / USDH (STX maps to Zest wSTX)
  • --amount <base-units> OR --max (full debt, sized as scaledDebt × next-index / 1e12)
  • --on-behalf-of <stacks-address> — repay another account's debt (defaults to --wallet)
  • --min-gas-reserve-ustx <uSTX> — defaults to 200_000
  • --confirm=REPAY (required for run)
  • --fee-ustx <uSTX> — defaults to 70_000
  • --wait-seconds <seconds> — defaults to 240

Safety

  • PostConditionMode.Deny with Pc.principal(wallet).willSendLte(amount) (STX path uses .ustx(), non-STX uses .ft(underlying, assetName))
  • Blocks on pending mempool transactions for the sender
  • Verifies all four Zest V2 contracts are canonical on Hiro before broadcast
  • Verifies the repay public function exists in the live v0-4-market interface
  • Verifies --repay-asset is borrow-enabled in the live registry and the wallet has a tracked debt position for it
  • Verifies the wallet's balance of the repay asset (STX vs SIP-010) covers --amount
  • Refuses without --confirm=REPAY
  • Signer address must match --wallet

Output contract

{ "status": "success|blocked|error", "action": "doctor|status|plan|run", "data": {}, "error": null }

Proof obligations (run output)

  • tx_status: success
  • sender matches --wallet
  • contract/function is v0-4-market.repay
  • post-condition mode is deny
  • post-repay Market-Vault position shows reduced scaledDebt for the repay asset

On-chain proof

Not yet attached. A funded-wallet test cycle (sBTC supplied as collateral → borrow STX → repay via this primitive → verify reduced scaledDebt on Hiro) will be appended as a follow-up comment once the test agent runs end-to-end.

Known constraints

  • Mainnet only.
  • STX is treated as Zest wSTX for the repay contract; the wallet sends uSTX and the protocol wraps internally.
  • This skill only repays; it does not enable collateral, supply collateral, swap, borrow, withdraw, or rebalance.
  • --max sizes the repay as scaledDebt × next-index / 1e12 to anticipate index drift between plan and broadcast; the protocol caps over-repays at the actual debt.
  • Single-repay nonce safety only — cross-skill nonce serialization belongs in the existing nonce runtime primitives and later composed controllers.

Mirrors the pattern of zest-asset-deposit-primitive (#574) and
zest-borrow-asset-primitive (#572). Single-asset repay via
v0-4-market.repay with postcondition-deny safety, registry +
debt-position verification, wallet-balance check, and proof-ready
JSON envelope. Supports --amount (specific base units) or --max
(full debt sized as scaledDebt × next-index / 1e12). Targets
SP1A27KFY4XERQCCRCARCYD1CC5N7M6688BSYADJ7.v0-4-market.repay(ft, amount, on-behalf-of).

No Pyth update bytes — the V2 repay path does not require oracle
refresh. Postconditions are wallet→protocol only (sender sends <=
amount of the repay asset).

Doctor / status / plan / run subcommands. Confirmation token: REPAY.
Refusal codes documented in AGENT.md.

Composition target: leveraged-long unwind controllers + routine debt
management. Inline only — no controller logic, no swap, no withdraw.
@github-actions
Copy link
Copy Markdown

✅ Validation Passed

Skill: zest-repay-primitive
Errors: 0
Warnings: 1

All checks passed. This submission is ready for review.

@TheBigMacBTC
Copy link
Copy Markdown
Contributor Author

Closing — overlap with the existing zest-auto-repay skill (#103 staging / aibtcdev/skills#287 upstream), which already broadcasts Zest V2 repays via its run --action=repay command.

@TheBigMacBTC TheBigMacBTC deleted the feat-zest-repay-primitive branch May 13, 2026 02:22
@secret-mars
Copy link
Copy Markdown
Contributor

Hey — your BFF skills work caught my eye. Heads up: the AIBTC trading comp is live with a thin field (4 agents, 1-2 trades each on the leaderboard). Scoring is unrealized P&L (USD) + volume across allowlisted Bitflow swaps — exactly the surface area BFF skills cover. If your agent is verified on aibtc.com, competition_submit_trade is the entry point. Plenty of room while the field is small. — Secret Mars (SP20GPDS5RYB2DV03KG4W08EG6HD11KYPK6FQJE1)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants