Skip to content

feat(quest-engine): deliver uncapped staking multiplier payouts - #103

Merged
Kaylahray merged 2 commits into
learnault:mainfrom
Birdmannn:main
Jul 29, 2026
Merged

feat(quest-engine): deliver uncapped staking multiplier payouts#103
Kaylahray merged 2 commits into
learnault:mainfrom
Birdmannn:main

Conversation

@Birdmannn

Copy link
Copy Markdown
Contributor

fix(quest-engine): deliver real boosted payouts on Build Quest approvals

Problem

The staking multiplier was being fetched in review_submission but the final
learner payout was silently capped back to base_learner_amount. A learner with
a 1.2x multiplier received exactly the same amount as an unstaked learner,
making staking incentives ineffective for B2B bounties.

Solution

Redesigned the approval payout in review_submission with an explicit two-source
funding model:

Source Covers
Quest escrow fee (15%) → RewardPool + base_learner_amount → learner
RewardPool boost_delta (boosted_amount − base) → learner

The quest escrow budget check (remaining >= quest.reward_amount) is preserved
unchanged. The boost delta is drawn from the RewardPool via distribute_reward,
which fails deterministically if the pool lacks sufficient balance — making the
funding constraint explicit and observable.

Basis-point math is unchanged: boosted = (base * multiplier) / 100.

Changes

contracts/quest-engine/src/lib.rs

  • Removed the cap that forced learner_amount back to base_learner_amount
  • After transferring fee + base from escrow, conditionally calls
    reward_pool.distribute_reward(contract, learner, boost_delta) when
    boost_delta > 0
  • consumed_amount continues to track only what is drawn from the quest escrow
    (quest.reward_amount), keeping budget accounting consistent

contracts/quest-engine/src/test.rs

  • Added MockStakeVault200 — a 200x (2.0×) multiplier vault for tier testing
  • Added MockRewardPoolTransfer — a mock RewardPool that actually transfers
    tokens, needed to verify end-to-end learner balances for boosted payouts
  • Added setup_with_boosted_multiplier() — wires MockStakeVaultWithMultiplier
    (120x) + MockRewardPoolTransfer into a full QuestEngine instance
  • Rewrote test_review_submission_with_120_multiplier to pre-fund the pool for
    the delta and assert the learner receives the real boosted amount (1020, not 850)
  • Renamed test_refund_after_capped_multiplier_returns_leftover_only
    test_refund_after_boosted_multiplier_escrow_is_fully_consumed with updated
    assertions matching the new accounting model

New acceptance-criteria tests:

Test Covers
test_staked_learner_receives_more_than_non_staked 120x learner earns more than 100x for the same quest
test_basis_point_math_for_100_120_200_multipliers Correct integer math for all three multiplier tiers
test_review_submission_with_200_multiplier_draws_delta_from_pool 200x tier end-to-end payout
test_review_submission_fails_deterministically_when_pool_cannot_cover_boost Contract panics when pool has no balance for the delta

Payout walkthrough (reward = 1000, multiplier = 120)

fee            = 1000 * 15 / 100        = 150   → RewardPool (from escrow)
base           = 1000 - 150             = 850   → learner    (from escrow)
boosted        = 850  * 120 / 100       = 1020
boost_delta    = 1020 - 850             = 170   → learner    (from RewardPool)
─────────────────────────────────────────────
learner total                           = 1020
escrow consumed                         = 1000  (fee + base)

Test results

running 59 tests
... all pass ...
test result: ok. 59 passed; 0 failed

Full workspace: 202 tests, 0 failures.
Closes #87

@Kaylahray
Kaylahray merged commit 8adbb3b into learnault:main Jul 29, 2026
1 check passed
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.

[QuestEngine] Deliver uncapped staking multiplier payouts

2 participants