ALEX Power Token (APower)

Non-transferable auto-compounding power token for the ALEX DeFi protocol — SIP-010 compliant with permanently disabled transfers

ContractSP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.token-apower
ProtocolALEX — leading DeFi platform on Stacks
SourceVerified on-chain via Hiro API (/v2/contracts/source)
Clarity VersionClarity 1 (pre-Clarity 4 — no as-contract? asset allowances)
Block Height45,455 (early mainnet deployment)
Lines of Code218
Audit Date2026-02-25
Auditorcocoa007.btc
Confidence🟢 HIGH — simple token contract, fully reviewed, all findings verified against on-chain source
0
Critical
0
High
2
Medium
2
Low
2
Info

Overview

APower is a non-transferable SIP-010 fungible token used in the ALEX protocol ecosystem. It implements the standard SIP-010 trait but permanently disables transfers — the transfer function always returns an error. Tokens can only be minted and burned by the contract owner or approved contracts.

The contract also provides a fixed-point math layer (8-decimal precision) with convenience wrappers like mint-fixed, burn-fixed, and mint-fixed-many for batch operations.

At deployment, ownership is transferred to .executor-dao and .alex-reserve-pool is added as an approved contract, indicating this token is managed by ALEX's DAO governance.

Documented Limitations

Findings

Medium

M-01: Mutable Decimals Corrupts Fixed-Point Math and Existing Balances

Location: set-decimals, pow-decimals, fixed-to-decimals, decimals-to-fixed

Description: The token-decimals variable can be changed by the owner at any time. Since the fixed-point conversion functions (fixed-to-decimals, decimals-to-fixed) dynamically read this variable, changing decimals after tokens have been minted causes all existing balances to be reinterpreted incorrectly.

(define-public (set-decimals (new-decimals uint))
  (begin
    (try! (check-is-owner))
    (ok (var-set token-decimals new-decimals))
  )
)

(define-private (pow-decimals)
  (pow u10 (unwrap-panic (get-decimals)))  ;; uses mutable var!
)

Impact: If decimals changes from 8 to 6, a user with 100 APower (stored as 10,000,000,000 raw units) would appear to have 10,000 APower through the fixed-point view. The mint-fixed and burn-fixed wrappers would also mint/burn incorrect raw amounts. Any protocol integrating with the fixed-point functions would break silently.

Recommendation: Make token-decimals a constant instead of a variable, or add a guard that only allows setting decimals before any tokens are minted (when total supply is 0).

Medium

M-02: Burn Without Sender Consent

Location: burn function

Description: The burn function allows any approved contract or owner to burn tokens from any sender address without requiring the sender's authorization. There is no check that sender == tx-sender or that the sender has approved the burn.

(define-public (burn (amount uint) (sender principal))
  (begin
    (asserts! (or (is-ok (check-is-approved)) (is-ok (check-is-owner))) ERR-NOT-AUTHORIZED)
    (ft-burn? apower amount sender)  ;; burns from arbitrary sender
  )
)

Impact: Any approved contract (currently .alex-reserve-pool) or the DAO owner can burn any user's APower balance without their consent. While this may be intentional for a protocol-managed token, it means users must fully trust all approved contracts. A compromised or malicious approved contract could wipe all user balances.

Recommendation: If unconditional burn is intended, document this trust assumption clearly. Otherwise, add (asserts! (is-eq sender tx-sender) ERR-NOT-AUTHORIZED) or require sender to be an approved contract as well. Note: Clarity's post-conditions can protect against unexpected burns at the transaction level.

Low

L-01: Transfer Permanently Disabled But SIP-010 Trait Implemented

Location: transfer function

Description: The transfer function always returns ERR-TRANSFER-FAILED regardless of parameters. The function doesn't even check its arguments — it ignores amount, sender, recipient, and memo entirely.

(define-public (transfer (amount uint) (sender principal) (recipient principal) (memo (optional (buff 34))))
  ERR-TRANSFER-FAILED
)

Impact: Any integration (DEX, wallet, or protocol) that attempts SIP-010 transfers will silently fail. While non-transferability is the design intent, implementing the full SIP-010 trait creates a false expectation of transferability. The transfer-fixed wrapper also always fails.

Recommendation: This is by design. Consider adding a comment in the source documenting the intentional non-transferability. Integrators should check for this pattern.

Low

L-02: tx-sender Auth Enables Transitive Privilege

Location: check-is-approved, check-is-owner

Description: Authorization checks use tx-sender instead of contract-caller. In Clarity, tx-sender is the original transaction signer and does not change through contract-to-contract calls. This means if an approved contract (A) calls another contract (B), and B calls token-apower.mint, the tx-sender check will see A (if A is the tx originator) — potentially allowing unintended transitive access.

(define-private (check-is-approved)
  (ok (asserts! (default-to false (map-get? approved-contracts tx-sender)) ERR-NOT-AUTHORIZED))
)

Impact: Low in practice since APower is non-transferable and protocol-managed. But if an approved contract has a public function that can be called by anyone, and that function triggers a chain leading to APower mint/burn, the tx-sender will be the approved contract's deployer principal — which may not be in the approved-contracts map. The real risk is if the contract-owner principal is used as tx-sender in a multi-step call.

Recommendation: Consider using contract-caller for the approved-contracts check to limit authorization to direct callers only. This is standard practice for Clarity access control.

Info

I-01: No Maximum Supply Cap

Location: (define-fungible-token apower)

Description: The token is defined without a maximum supply parameter. Clarity's define-fungible-token accepts an optional max supply — omitting it means supply is unlimited.

Impact: The owner or any approved contract can mint unlimited tokens. For a protocol-managed auto-compounding token, this may be intentional, but it means there is no on-chain supply ceiling enforced at the language level.

Recommendation: If a maximum supply is intended, add it to the token definition. Otherwise, this is acceptable for a protocol-managed token where supply is controlled by governance.

Info

I-02: Redundant Authorization in Batch Mint

Location: mint-fixed-many

Description: The mint-fixed-many function performs an authorization check, then calls mint-fixed-many-itermint-fixedmint, which performs the same authorization check again for each item in the list.

(define-public (mint-fixed-many (recipients (list 200 {amount: uint, recipient: principal})))
  (begin
    (asserts! (or (is-ok (check-is-approved)) (is-ok (check-is-owner))) ERR-NOT-AUTHORIZED)
    (ok (map mint-fixed-many-iter recipients))  ;; each iter calls mint → re-checks auth
  )
)

Impact: Wastes runtime costs by checking authorization 201 times (1 + 200 iterations) instead of once. No security impact — it's just inefficient.

Recommendation: Create an internal mint-unchecked private function for use by mint-fixed-many-iter after the outer auth check. This saves gas on batch operations.

Architecture Notes

The contract follows a common ALEX pattern:

The fixed-point layer uses ONE_8 = 10^8 as the base unit. The conversion functions multiply/divide between raw and fixed representations. This is sound as long as decimals remains at 8 (the default), aligning 1:1 with the fixed-point base — but fragile if decimals is ever changed (see M-01).

Conclusion

APower is a straightforward non-transferable token with a clean implementation. The main concerns are the mutable decimals (M-01) which could break fixed-point math, and the unchecked burn target (M-02) which requires trust in all approved contracts. Neither is critical given the token's non-transferable nature and DAO governance, but both represent avoidable risk.

The contract has been deployed since early mainnet (block 45,455) and is managed by ALEX's executor-dao. Its simplicity is a strength — there are no complex interactions or reentrancy vectors.

Overall risk: Low-Medium. The trust model is centralized (DAO + approved contracts), which is appropriate for a protocol-internal accounting token.