Skip to content

feat(stablecoin): implement withdraw_collateral (#92)#112

Open
gravityblast wants to merge 2 commits into
mainfrom
stablecoin/withdraw-collateral
Open

feat(stablecoin): implement withdraw_collateral (#92)#112
gravityblast wants to merge 2 commits into
mainfrom
stablecoin/withdraw-collateral

Conversation

@gravityblast
Copy link
Copy Markdown
Collaborator

@gravityblast gravityblast commented May 19, 2026

closes #92

Note: fee accrual and post-withdrawal collateralization checks are defered to be implemented together with generate_debt.

@gravityblast gravityblast requested a review from 3esmit May 19, 2026 14:00
@gravityblast gravityblast force-pushed the stablecoin/withdraw-collateral branch from 3a8e5c3 to b7257ad Compare May 19, 2026 14:02
@3esmit 3esmit requested a review from Copilot May 19, 2026 14:39
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements the withdraw_collateral instruction for the stablecoin program (closes #92). The implementation mirrors the conventions established in open_position: validate inputs, decode the Position, verify position/vault PDAs, and emit a chained Token::Transfer from the vault to the destination under the vault's PDA authority. As called out in issue #92, full functionality requires stability fee accrual and a collateralization-ratio check (issues #95/#96/#97); until those land, the instruction hard-asserts Position.debt_amount == 0.

Changes:

  • Adds withdraw_collateral core logic that validates accounts, decrements Position.collateral_amount, and emits a chained Token::Transfer.
  • Wires the instruction into the guest entrypoint and the Instruction enum, regenerating the stablecoin IDL.
  • Adds 12 new unit tests covering the happy path, edge cases (zero/full drain), and each panic precondition.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
File Description
stablecoin/src/withdraw_collateral.rs New module implementing the instruction's logic, account validation, and chained transfer emission.
stablecoin/src/lib.rs Exposes the new withdraw_collateral module.
stablecoin/src/tests.rs New helper constructors and 12 unit tests for the happy path and all panic preconditions.
stablecoin/core/src/lib.rs Adds the WithdrawCollateral { amount } variant to the Instruction enum with account-list documentation.
stablecoin/methods/guest/src/bin/stablecoin.rs Guest-side #[instruction] wrapper that delegates to withdraw_collateral.
artifacts/stablecoin-idl.json Regenerated IDL entry for the new instruction.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Collaborator

@3esmit 3esmit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a test that gives the vault a balance matching Position.collateral_amount and either executes the emitted transfer through token_program::transfer::transfer or, better, adds an integration test that opens a stablecoin position and then withdraws from it through LEZ chained-call execution

Comment thread stablecoin/src/tests.rs
let (post_states, chained_calls) = crate::withdraw_collateral::withdraw_collateral(
owner_account(),
init_position_account(initial_collateral, 0),
init_vault_account(),
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vault account is initialized with balance 0

Comment thread stablecoin/src/tests.rs
#[test]
fn withdraw_collateral_updates_position_and_emits_transfer() {
let initial_collateral: u128 = 500;
let amount: u128 = 200;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Withdraw requests for 200

Comment thread stablecoin/src/tests.rs
},
)
.with_pda_seeds(vec![compute_position_vault_pda_seed(position_id())]);
assert_eq!(chained_calls[0], expected_transfer);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only checks if Transfer is emmited, but the downstream token program would reject the transfer because it does not have balance.

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.

Implement withdraw_collateral

3 participants