Repository navigation
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Brings main into this branch through feedback. Conflict in docs/kit-spec.md: keep this branch's setup rules, with formulas in GitHub's dollar-backtick delimiters, as main now writes them.
luchobonatti
left a comment
There was a problem hiding this comment.
One thing worth a look: vault_unfrozen reads is_frozen, which OZ only sets on a full freeze. A partial freeze on the vault's address before bind_vault would still pass finish_setup, and cancel_redeem hands escrow back through a SEP-41 transfer, which respects it. Would also requiring get_frozen_tokens(vault) == 0 close that window?
The console still calls forced_transfer as compliance (useComplianceTransactions.ts:43), which this makes manager-only — filed #338 to move it to legal_transfer with the co-signature.
|
Superseded by #264: escrow returns now use the manager |
Summary
Closes #319
Until now the compliance key alone could move any holder's shares, the vault's escrow included, and freeze the vault's address. A legal-order transfer now needs governance's signature in the same call, never moves shares out of or into the vault's address, and only lands on an allowlisted account. A recovery needs the same co-signature and goes only to the new address the identity verifier names. Both move wallet shares only; value the vault holds for a frozen holder waits for an unfreeze.
Changes
legal_transfer(from, to, amount, reference, operator): compliance asks, the token admin co-signs, two different accounts; publishesLegalTransferwith the order referenceforced_transferis manager-only; the vault's escrow is unchangedrecover_balanceneeds the admin's co-signature and never moves shares out of or into the vault's addressVaultAddress); unfreezing it stays possiblehealth()reportsvault_unfrozen, and the vault'sfinish_setuprefuses while its address is frozenvault_unfrozen; the docs describe the co-signatureDeviations
recover_balancealso refuses the vault as the new account: OpenZeppelin's recovery copies a freeze onto it.grant_roleduring setup; this base does not refuse that grant yet.Miswire::VaultFrozen, frozen through the token beforebind_vault, instead of a new test incontrols.rs.Acceptance criteria
legal_transferneeds the compliance authority and the admin as two different accounts in one callforced_transferis manager-only; the vault's escrow still worksrecover_balanceneeds the admin's co-signature and never moves the vault's balancefinish_setuprefuses while its address is frozenTest plan
Automated tests
CARGO_TARGET_DIR=<repo>/target SOROBAN_SDK_BUILD_SYSTEM_SUPPORTS_SPEC_SHAKING_V2=1 cargo test --locked -p share-token legal_transfer: 13 tests pass.CARGO_TARGET_DIR=<repo>/target SOROBAN_SDK_BUILD_SYSTEM_SUPPORTS_SPEC_SHAKING_V2=1 cargo test --locked: the workspace passes (share-token 64, async-vault 370), includingevery_wiring_step_is_checked_before_setup_finishesandeach_missing_wiring_step_shows_in_its_own_flagwith the frozen vault.npm run deploy, thentest:happy-path(24/24),test:guards(46/46) andtest:wind-down(6/6). The deploy prints"vault_unfrozen":true.Manual verification
On the same local network, a script signed as compliance: alone, the SDK asks for governance's signature; co-signed by governance, one share moved; from or to the vault, and freezing the vault, returned
VaultAddress; compliance'sforced_transferreturnedUnauthorized.Breaking changes
forced_transferrefuses the compliance role. On the next deployment the console's compliance transfer must calllegal_transferwith governance's co-signature, and recovery needs it too.health()gainsvault_unfrozen, and the token's spec gainslegal_transfer, theLegalTransferevent and errors 7012, 7013 and 7015, so clients must be regenerated.Checklist
Screenshots
None.