Collateral token registry for the Arkadiko Vaults system. Stores token parameters (max debt, stability fees, liquidation ratios, redemption fees) used by the vault manager. Pure configuration contract โ holds no funds and moves no tokens. Admin functions are DAO-gated. The primary risk is misconfiguration via unvalidated parameter updates.
| Severity | Count |
|---|---|
| Critical | 0 |
| High | 0 |
| Medium | 1 |
| Low | 1 |
| Informational | 3 |
The contract is a straightforward key-value registry:
(list 25 principal) data-var tracking registered collateral typesset-token (add/update) and remove-token, both gated by arkadiko-dao get-dao-ownerImplements arkadiko-vaults-tokens-trait-v1-1.vaults-tokens-trait. No token transfers, no as-contract, no custody.
set-tokenLocation: set-token function
Description: The set-token function accepts arbitrary uint values for all parameters with no sanity checks. A DAO owner mistake (or compromise) could set catastrophic values:
liquidation-ratio: u0 โ vaults become unliquidatable regardless of collateral ratiomax-debt: u0 โ effectively freezes new vault creation for that tokenstability-fee: u10000 (100%) โ drains vault owners via feesvault-min-debt: u0 โ enables dust vaults that are uneconomical to liquidate(define-public (set-token
(token principal)
(token-name (string-ascii 12))
(max-debt uint) ;; no minimum
(vault-min-debt uint) ;; no minimum
(stability-fee uint) ;; no maximum
(liquidation-ratio uint) ;; no minimum โ u0 breaks liquidation math
...
)
(begin
(asserts! (is-eq contract-caller (contract-call? .arkadiko-dao get-dao-owner)) (err ERR_NOT_AUTHORIZED))
;; No parameter validation โ values go straight to map
(map-set tokens { token: token } { ... })
(ok true)
)
)
Impact: Downstream contracts (vault manager, liquidation engine) consume these parameters directly. Invalid values could brick vault operations, prevent liquidations, or enable undercollateralized minting. The blast radius depends on how the vault manager validates these inputs โ if it trusts this registry blindly, the impact is systemic.
Recommendation: Add minimum bounds for critical parameters:
(asserts! (>= liquidation-ratio u10000) (err ERR_INVALID_PARAM)) ;; min 100%
(asserts! (> vault-min-debt u0) (err ERR_INVALID_PARAM))
(asserts! (<= stability-fee u5000) (err ERR_INVALID_PARAM)) ;; max 50%
Description: Contract does not use Clarity 4 features. However, since this contract has no as-contract calls and performs no token transfers, the practical impact is negligible. The contract cannot benefit from as-contract? with asset allowances because it never moves assets.
Impact: Minimal. Noted for completeness โ a Clarity 4 redeployment would gain contract-hash? for verifiability but provides no security improvement for this contract's functionality.
Description: All parameter changes route through a single arkadiko-dao get-dao-owner check. This is standard for Arkadiko's architecture and matches the pattern seen across their contract suite. The DAO owner can modify any token's parameters or remove tokens entirely in a single transaction.
Impact: Documented trust assumption. If the DAO owner key is compromised, an attacker could silently modify liquidation ratios to prevent liquidations, then open undercollateralized vaults through a separate contract interaction.
Description: Neither set-token nor remove-token emit print events. Parameter changes are only visible by polling the contract's map state. Off-chain monitoring systems and governance dashboards cannot subscribe to configuration changes.
Recommendation: Add (print { event: "token-updated", token: token, ... }) to admin functions for off-chain observability.
Description: The remove-token function uses a data-var token-to-remove as a closure workaround for the filter builtin, since Clarity's filter only accepts a named function (no closures). This is a well-known Clarity idiom and is safe in the single-transaction context (Clarity has no concurrency). However, the data-var persists after the transaction completes, leaving a stale value.
(define-data-var token-to-remove principal tx-sender)
(define-public (remove-token (token principal))
(begin
...
(var-set token-to-remove token)
(var-set token-list (filter is-token-to-remove (var-get token-list)))
(ok true)
)
)
(define-read-only (is-token-to-remove (token principal))
(not (is-eq token (var-get token-to-remove)))
)
Impact: None โ the stale value is harmless since token-to-remove is only read during the filter call within the same transaction. Standard Clarity pattern.
as-max-len? returns an error instead of silently failing when the 25-token cap is reachedindex-of? before appending to avoid duplicate list entriesSource fetched from Hiro API (on-chain canonical source). Full manual review of all functions, data structures, and initialization block. Cross-referenced with previously audited Arkadiko contracts (vaults-manager-v1-1, freddie-v1-1, auction-engine-v4-3, oracle-v2-3) to understand how this registry's parameters flow into the broader system.