Smart Contract

FlowYieldVaultsClosedBeta

A.b1d63873c3cc9f79.FlowYieldVaultsClosedBeta

Valid From

143,267,141

Deployed

1w ago
Feb 19, 2026, 10:35:24 AM UTC

Dependents

39 imports
1access(all) contract FlowYieldVaultsClosedBeta {
2
3    access(all) entitlement Admin
4    access(all) entitlement Beta
5
6    access(all) resource BetaBadge {
7        access(all) let assignedTo: Address
8        init(_ addr: Address) {
9            self.assignedTo = addr
10        }
11        access(all) view fun getOwner(): Address {
12            return self.assignedTo
13        }
14    }
15
16    // --- Paths ---
17    access(all) let UserBetaCapStoragePath: StoragePath
18    access(all) let AdminHandleStoragePath: StoragePath
19
20    // --- Registry: which capability was issued to which address, and revocation flags ---
21    access(all) struct AccessInfo {
22        access(all) let capID: UInt64
23        access(all) let isRevoked: Bool
24
25        init(_ capID: UInt64, _ isRevoked: Bool) {
26            self.capID = capID
27            self.isRevoked = isRevoked
28        }
29    }
30    access(all) var issuedCapIDs: {Address: AccessInfo}
31
32    // --- Events ---
33    access(all) event BetaGranted(addr: Address, capID: UInt64)
34    access(all) event BetaRevoked(addr: Address, capID: UInt64?)
35
36    /// Per-user badge storage path (under the *contract/deployer* account)
37    access(contract) fun _badgePath(_ addr: Address): StoragePath {
38        return StoragePath(identifier: "FlowYieldVaultsBetaBadge_".concat(addr.toString()))!
39    }
40
41    /// Ensure the admin-owned badge exists for the user
42    access(contract) fun _ensureBadge(_ addr: Address) {
43        let p = self._badgePath(addr)
44        if self.account.storage.type(at: p) == nil {
45            self.account.storage.save(<-create BetaBadge(addr), to: p)
46        }
47    }
48
49    access(contract) fun _destroyBadge(_ addr: Address) {
50        let p = self._badgePath(addr)
51        if let badge <- self.account.storage.load<@BetaBadge>(from: p) {
52            destroy badge
53        }
54    }
55
56    /// Issue a capability from the contract/deployer account and record its ID
57    access(contract) fun _issueBadgeCap(_ addr: Address): Capability<auth(Beta) &BetaBadge> {
58        let p = self._badgePath(addr)
59        let cap: Capability<auth(Beta) &BetaBadge> =
60            self.account.capabilities.storage.issue<auth(Beta) &BetaBadge>(p)
61
62        self.issuedCapIDs[addr] = AccessInfo(cap.id, false)
63
64        if let ctrl = self.account.capabilities.storage.getController(byCapabilityID: cap.id) {
65            ctrl.setTag("flowyieldvaults-beta")
66        }
67
68        emit BetaGranted(addr: addr, capID: cap.id)
69        return cap
70    }
71
72    /// Clean up any previously issued controller before issuing a fresh capability.
73    access(contract) fun _cleanupExistingGrant(_ addr: Address) {
74        if let info = self.issuedCapIDs[addr] {
75            if let ctrl = self.account.capabilities.storage.getController(byCapabilityID: info.capID) {
76                ctrl.delete()
77                emit BetaRevoked(addr: addr, capID: info.capID)
78            }
79        }
80    }
81
82    /// Delete the recorded controller, revoking *all copies* of the capability
83    access(contract) fun _revokeByAddress(_ addr: Address) {
84        let info = self.issuedCapIDs[addr] ?? panic("No cap recorded for address")
85        let ctrl = self.account.capabilities.storage.getController(byCapabilityID: info.capID)
86            ?? panic("Missing controller for recorded cap ID")
87        ctrl.delete()
88        self.issuedCapIDs[addr] = AccessInfo(info.capID, true)
89        self._destroyBadge(addr)
90        emit BetaRevoked(addr: addr, capID: info.capID)
91    }
92
93    // 2) A small in-account helper resource that performs privileged ops
94    access(all) resource AdminHandle {
95        access(Admin) fun grantBeta(addr: Address): Capability<auth(FlowYieldVaultsClosedBeta.Beta) &FlowYieldVaultsClosedBeta.BetaBadge> {
96            FlowYieldVaultsClosedBeta._cleanupExistingGrant(addr)
97            FlowYieldVaultsClosedBeta._ensureBadge(addr)
98            return FlowYieldVaultsClosedBeta._issueBadgeCap(addr)
99        }
100
101        access(Admin) fun revokeByAddress(addr: Address) {
102            FlowYieldVaultsClosedBeta._revokeByAddress(addr)
103        }
104    }
105
106    /// Read-only check used by any gated entrypoint
107    access(all) view fun getBetaCapID(_ addr: Address): UInt64? {
108        if let info = self.issuedCapIDs[addr] {
109            if info.isRevoked {
110                return nil
111            }
112            return info.capID
113        }
114        return nil
115    }
116
117    access(all) view fun validateBeta(_ addr: Address?, _ betaRef: auth(Beta) &BetaBadge): Bool {
118        if addr == nil {
119            return false
120        }
121        let recordedID: UInt64? = self.getBetaCapID(addr!)
122        if recordedID == nil {
123            return false
124        }
125
126        if betaRef.getOwner() != addr {
127            return false
128        }
129
130        return true
131    }
132
133    init() {
134        self.AdminHandleStoragePath = StoragePath(
135            identifier: "FlowYieldVaultsClosedBetaAdmin_\(self.account.address)"
136        )!
137        self.UserBetaCapStoragePath = StoragePath(
138            identifier: "FlowYieldVaultsUserBetaCap_\(self.account.address)"
139        )!
140
141        self.issuedCapIDs = {}
142
143        // Create and store the admin handle in *this* (deployer) account
144        self.account.storage.save(<-create AdminHandle(), to: self.AdminHandleStoragePath)
145    }
146}
147