Incentive Contract Design
Cap-based Move architecture for the LiquidLink incentive system.
LiquidLink v2 Incentive Contract Design (Cap-based, Draft)
Scope: on-chain scoring updated directly by authorized project contracts via capability objects (cap/borrow), optional time-weighted mechanics using integer math, multi-SKU redemption into restricted vouchers (non-coin), public verification via on-chain state (events are audit/logging only), modular architecture with an optional upgrade surface.
Assumptions
- Platform: Move (Sui/IOTA), integer math only.
- Time source: blockchain timestamp (milliseconds) via
Clockwhere available. - Units: pure integers; if finer granularity is needed later, scale by a fixed factor (e.g., 1e6).
- No reverse redemption; vouchers are consumable and non-free-transfer.
Roles
- Admin (LiquidLink): grants project capabilities, manages SKU catalog, emergency controls.
- Project(s): on-chain contracts that hold a project capability, create their own scoreboard, and update points within user transactions (no off-chain indexer required).
- Any user: can read/verify points from on-chain state; can redeem if they have points.
- Observers: can index events for analytics/audits, but events are not required to derive state.
Authorization Model (cap/borrow)
ProtocolAdminCapis minted at publish/init and owned by the protocol admin.- A
Scoreboardis a shared object that stores point-related state and aproject_id. - Admin grants a project a
ProjectCap, and issues aPointCapbound to the sameproject_id. - The project creates its own
ScoreboardusingProjectCap, which writes the sameproject_idinto the scoreboard. - Every mutation must assert
cap.project_id == scoreboard.project_idto prevent cross-project misuse.
Modules (current repo layout; may evolve)
scoreboard:Scoreboardstorage + admin caps and constructors.config: capability helpers (e.g.,PointCap) and optional scoring config.mutate: point mutations requiringPointCapand a mutable borrow ofScoreboard.- (planned)
redeem: reward SKU registry + voucher issuance/burning. - (optional)
router: upgrade surface if the package needs version routing.
Data Structures (conceptual)
struct Scoreboard has key {
id: UID,
project_id: ID,
score: Table<address, u64>,
stake: Table<address, u64>,
timestamp: Table<address, u64>,
// (planned) rewards/vouchers tables
}
struct ProtocolAdminCap has key, store { id: UID }
struct ProjectCap has key, store {
id: UID
}
struct PointCap has key, store {
id: UID,
project_id: ID, // binds capability to a project
}Entry Interfaces (cap-based)
Admin:
create_incentive_system(protocol, client)→ issuesProjectCap+PointCaptoclient.
Project (authorized by cap):
create_scoreboard(project_cap, kind)→ creates and shares aScoreboardbound to the project.add_point(point_cap, scoreboard, amount)→ add points to the transaction sender (or a target if an extended API is added later).subtract_point(point_cap, scoreboard, amount)→ subtract/clamp points for the transaction sender.set_linear_time_point(point_cap, scoreboard, score_per_duration, duration, clock)/update_linear_time_point(...)→ optional linear-time scoring.
Public:
get_points(scoreboard, owner, now)(view) → returns current points (and any time-weighted derived value) without writing state.
Redeem (planned):
register_reward(...),update_reward(...)(admin)redeem(scoreboard, sku_id, amount)(user) → deduct points, mint a restricted voucher.
Events (logging only)
Emit events on:
- scoreboard creation / capability issuance & revocation
- point mutations (add/subtract/linear-time set/update)
- reward SKU changes and redemption
Events are for audit/indexing only; Scoreboard state is the source of truth.
Invariants & Checks
- Capability authorization: only holders of the correct cap can mutate a scoreboard.
- Binding check: cap
project_idmust match the scoreboard being mutated. - Points must not underflow (default: clamp at 0).
- (if enabled) linear-time score updates must be deterministic and verifiable.
Open Decisions
- Whether negative balances are allowed vs clamp-to-0.
- Whether to encode per-project quotas/time windows in
ProjectCapor inScoreboardstorage. - Exact time-weighted formula (stake-based vs rate-based) and what is verifiable on-chain.