feat(guilds): legion-engage — no-admin refundable engagement stake#5
Open
biwasxyz wants to merge 1 commit into
Open
feat(guilds): legion-engage — no-admin refundable engagement stake#5biwasxyz wants to merge 1 commit into
biwasxyz wants to merge 1 commit into
Conversation
Providers optionally stake sBTC to join a legion and unlock benefits (ranking, treasury share, governance). Staking is NOT required to earn. - No admin, no slash: nothing can seize a member's stake. - join / add-stake / leave; leave refunds 90% and routes a 10% exit fee into the legion treasury (via deposit, so it stays governable). - get-stake read used by the gateway for stake-weighted ranking. - Clarinet tests: 7 new, all passing (11/11 with the existing suite). Not deployed. For CEO review.
arc0btc
approved these changes
Jul 3, 2026
arc0btc
left a comment
There was a problem hiding this comment.
Reviewed legion-engage.clar + engage.test.ts against the existing legion-treasury.clar (not in this diff) to verify the cross-contract fee routing actually works, not just that it type-checks.
What works well:
- No-admin/no-slash design matches the PR's stated goal —
map-delete+ balance transfer inleaveis the only way a stake moves, and it's always initiated by the member themselves. - Checks-effects-interactions is correctly followed in
leave:map-delete+var-set TotalStakedhappen before either token transfer. Not strictly required here sinceSBTCis a fixed, trusted trait-checked constant (no reentrancy surface), but it's the right habit anyway. - Verified the treasury hop is correct, not just plausible.
leavecalls(as-contract (contract-call? .legion-treasury deposit ft fee)). Insidelegion-treasury.deposit, the transfer is(contract-call? ft transfer amount tx-sender (as-contract tx-sender) none)—tx-senderthere resolves tolegion-engage's principal (because of the outeras-contractwrap), and(as-contract tx-sender)resolves to the treasury's own principal (because that's the contract currently executing). So the fee correctly moves engage → treasury, and it satisfies a typical SIP-010sender == tx-senderguard. This is a subtle nested-as-contractinteraction that's easy to get backwards; it's implemented correctly here. - Test coverage is good for the contract's size: min-stake boundary, double-join rejection, add-stake, the 90/10 leave split (both the member's net cost and the treasury's balance delta),
quote-exitparity with actualleaveoutput, and not-a-member guards onleave/add-stake. - Dust from the integer-division fee rounds in the member's favor (
refund = stake - fee), which is the safer direction.
Minor, non-blocking:
- In
leave,feeandrefundeach independently recompute(get stake m)instead of reusing the already-bounds:Same result, just three lookups where one would do — worth tightening for readability but not correctness.(s (get stake m)) (fee (/ (* (get stake m) EXIT_FEE_BPS) u10000)) ;; could be (* s EXIT_FEE_BPS) (refund (- (get stake m) (/ (* (get stake m) EXIT_FEE_BPS) u10000))) ;; could be (- s fee)
EXIT_FEE_BPSis a hardcoded constant with no runtime assertion that it's<= u10000; fine today since it's compile-time and set once, but if this ever becomes configurable it'd need a bounds check to avoidrefundunderflowing.
No blocking issues. Approving.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
New
legion-engagecontract: providers optionally stake to join a legion and unlock benefits (ranking, treasury share, governance). Staking is never required to earn — earning is free at the gateway.Why
Moves away from the bond/slash/admin model of
legion-providers. There is no admin and no slash — nothing can seize a member's stake. Cheating enforcement lives off-chain at the gateway (de-route), not on-chain confiscation.Behavior
join(ft, amount)— lock sBTC (min 10k sats), become a member.add-stake(ft, amount)— top up.leave(ft)— refund 90% to the member, route the 10% exit fee into the legion treasury (viadeposit, so it stays governable).get-stake(who)— read used by the gateway for stake-weighted ranking.Tests
Clarinet/vitest: 7 new tests, all passing (11/11 with the existing guild suite).
Not deployed
Nothing deployed. For review; deploy awaits sign-off.