Source Code

(define-fungible-token share-token)

(define-map vault-assets
    principal
    { asset-address: principal, balance: uint }
)

(define-map asset-list
    uint
    principal
)

(define-map user-shares
    { user: principal, asset: principal }
    uint
)

(define-data-var total-assets uint u0)
(define-data-var asset-count uint u0)

(define-constant contract-owner tx-sender)
(define-constant err-not-owner (err u100))
(define-constant err-invalid-amount (err u101))
(define-constant err-asset-not-found (err u102))
(define-constant err-insufficient-shares (err u103))

(define-read-only (get-vault-asset (asset principal))
    (ok (map-get? vault-assets asset))
)

(define-read-only (get-asset-count)
    (ok (var-get asset-count))
)

(define-read-only (get-user-shares (user principal) (asset principal))
    (ok (default-to u0 (map-get? user-shares { user: user, asset: asset })))
)

(define-read-only (get-total-assets)
    (ok (var-get total-assets))
)

(define-public (add-asset (asset-address principal))
    (let
        (
            (count (var-get asset-count))
        )
        (asserts! (is-eq tx-sender contract-owner) err-not-owner)
        (map-set vault-assets asset-address
            { asset-address: asset-address, balance: u0 }
        )
        (map-set asset-list count asset-address)
        (var-set asset-count (+ count u1))
        (ok true)
    )
)

(define-public (deposit (asset principal) (amount uint))
    (let
        (
            (asset-data (unwrap! (map-get? vault-assets asset) err-asset-not-found))
            (current-balance (get balance asset-data))
            (current-shares (default-to u0 (map-get? user-shares { user: tx-sender, asset: asset })))
        )
        (asserts! (> amount u0) err-invalid-amount)
        (map-set vault-assets asset
            { asset-address: asset, balance: (+ current-balance amount) }
        )
        (map-set user-shares { user: tx-sender, asset: asset }
            (+ current-shares amount)
        )
        (var-set total-assets (+ (var-get total-assets) amount))
        (ok true)
    )
)

(define-public (withdraw (asset principal) (amount uint))
    (let
        (
            (asset-data (unwrap! (map-get? vault-assets asset) err-asset-not-found))
            (current-balance (get balance asset-data))
            (current-shares (default-to u0 (map-get? user-shares { user: tx-sender, asset: asset })))
        )
        (asserts! (>= current-shares amount) err-insufficient-shares)
        (map-set vault-assets asset
            { asset-address: asset, balance: (- current-balance amount) }
        )
        (map-set user-shares { user: tx-sender, asset: asset }
            (- current-shares amount)
        )
        (var-set total-assets (- (var-get total-assets) amount))
        (ok true)
    )
)

(define-public (transfer-shares (asset principal) (amount uint) (recipient principal))
    (let
        (
            (sender-shares (default-to u0 (map-get? user-shares { user: tx-sender, asset: asset })))
            (recipient-shares (default-to u0 (map-get? user-shares { user: recipient, asset: asset })))
        )
        (asserts! (>= sender-shares amount) err-insufficient-shares)
        (map-set user-shares { user: tx-sender, asset: asset }
            (- sender-shares amount)
        )
        (map-set user-shares { user: recipient, asset: asset }
            (+ recipient-shares amount)
        )
        (ok true)
    )
)

Functions (8)

FunctionAccessArgs
get-vault-assetread-onlyasset: principal
get-asset-countread-only
get-user-sharesread-onlyuser: principal, asset: principal
get-total-assetsread-only
add-assetpublicasset-address: principal
depositpublicasset: principal, amount: uint
withdrawpublicasset: principal, amount: uint
transfer-sharespublicasset: principal, amount: uint, recipient: principal