Skip to content

Commit 47eb7ea

Browse files
committed
tweak cap
1 parent 1759357 commit 47eb7ea

3 files changed

Lines changed: 62 additions & 36 deletions

File tree

cadence/contracts/TidalYieldClosedBeta.cdc

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,29 +18,53 @@ access(all) contract TidalYieldClosedBeta {
1818
access(all) event BetaGranted(addr: Address, capID: UInt64)
1919
access(all) event BetaRevoked(addr: Address, capID: UInt64?)
2020

21+
/// Per-user badge storage path (under the *contract/deployer* account)
22+
access(contract) fun _badgePath(_ addr: Address): StoragePath {
23+
return StoragePath(identifier: "TY_BetaBadge_".concat(addr.toString()))!
24+
}
25+
26+
/// Ensure the admin-owned badge exists for the user
27+
access(contract) fun _ensureBadge(_ addr: Address) {
28+
let p = self._badgePath(addr)
29+
if self.account.storage.type(at: p) == nil {
30+
self.account.storage.save(<-create BetaBadge(), to: p)
31+
}
32+
}
33+
34+
/// Issue a capability from the contract/deployer account and record its ID
35+
access(contract) fun _issueBadgeCap(_ addr: Address): Capability<&{TidalYieldClosedBeta.IBeta}> {
36+
let p = self._badgePath(addr)
37+
let cap: Capability<&{TidalYieldClosedBeta.IBeta}> =
38+
self.account.capabilities.storage.issue<&{TidalYieldClosedBeta.IBeta}>(p)
39+
self.issuedCapIDs[addr] = cap.id
40+
41+
if let ctrl = self.account.capabilities.storage.getController(byCapabilityID: cap.id) {
42+
ctrl.setTag("tidalyield-beta")
43+
}
44+
45+
emit BetaGranted(addr: addr, capID: cap.id)
46+
return cap
47+
}
48+
49+
/// Delete the recorded controller, revoking *all copies* of the capability
50+
access(contract) fun _revokeByAddress(_ addr: Address) {
51+
let id = self.issuedCapIDs[addr] ?? panic("No cap recorded for address")
52+
let ctrl = self.account.capabilities.storage.getController(byCapabilityID: id)
53+
?? panic("Missing controller for recorded cap ID")
54+
ctrl.delete()
55+
self.issuedCapIDs.remove(key: addr)
56+
emit BetaRevoked(addr: addr, capID: id)
57+
}
58+
2159
// 2) A small in-account helper resource that performs privileged ops
2260
access(all) resource AdminHandle {
23-
access(Admin) fun grantBeta(addr: Address): Capability<&{TidalYieldClosedBeta.BetaBadge}> {
24-
// Store a badge under a path derived from the user address, but in ADMIN storage
25-
let path = StoragePath(identifier: "TY_BetaBadge_".concat(addr.toString()))!
26-
// create only once
27-
if self.account.storage.type(at: path) == nil {
28-
self.account.storage.save(<-create TidalYieldClosedBeta.BetaBadge(addr), to: path)
29-
}
30-
// Issue a capability FROM ADMIN (controller in admin)
31-
let cap: Capability<&{TidalYieldClosedBeta.BetaBadge}> =
32-
self.account.capabilities.storage.issue<&{TidalYieldClosedBeta.BetaBadge}>(path)
33-
TidalYieldClosedBeta.issuedCapIDs[addr] = cap.id
34-
35-
return cap
61+
access(Admin) fun grantBeta(addr: Address): Capability<&{TidalYieldClosedBeta.IBeta}> {
62+
TidalYieldClosedBeta._ensureBadge(addr)
63+
return TidalYieldClosedBeta._issueBadgeCap(addr)
3664
}
3765

3866
access(Admin) fun revokeByAddress(addr: Address) {
39-
let id = TidalYieldClosedBeta.issuedCapIDs[addr] ?? panic("No cap recorded")
40-
let ctrl = self.account.capabilities.storage.getController(byCapabilityID: id)
41-
?? panic("Missing controller")
42-
ctrl.delete()
43-
TidalYieldClosedBeta.issuedCapIDs.remove(key: addr)
67+
TidalYieldClosedBeta._revokeByAddress(addr)
4468
}
4569
}
4670

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,30 @@
11
import "TidalYieldClosedBeta"
22

33
/// Saves a copy of the admin-issued cap into the user's account
4-
/// and (optionally) publishes it under /public for easy script checks.
5-
transaction(publishPublic: Bool) {
4+
/// and publishes it under /public for easy script checks.
5+
transaction() {
66

77
prepare(
88
admin: auth(Capabilities) &Account,
99
user: auth(Storage, Capabilities) &Account
1010
) {
11-
// 1) Admin issues (controller lives in ADMIN)
1211
let adminCap: Capability<auth(TidalYieldClosedBeta.Admin) &TidalYieldClosedBeta.AdminHandle> =
13-
admin.capabilities.storage.issue<auth(TidalYieldClosedBeta.Admin) &TidalYieldClosedBeta.AdminHandle>(
14-
TidalYieldClosedBeta.AdminHandleStoragePath
15-
)
12+
admin.capabilities.storage.issue<auth(TidalYieldClosedBeta.Admin) &TidalYieldClosedBeta.AdminHandle>(
13+
TidalYieldClosedBeta.AdminHandleStoragePath
14+
)
1615
let handle: auth(TidalYieldClosedBeta.Admin) &TidalYieldClosedBeta.AdminHandle =
17-
adminCap.borrow() ?? panic("Missing AdminHandle")
16+
adminCap.borrow() ?? panic("Missing AdminHandle")
17+
18+
let cap: Capability<&{TidalYieldClosedBeta.IBeta}> =
19+
handle.grantBeta(addr: user.address)
1820

19-
let cap: Capability<&{TidalYieldClosedBeta.BetaBadge}> =
20-
handle.grantBeta(addr: user.address)
21+
user.storage.save(cap, to: TidalYieldClosedBeta.BetaBadgeStoragePath)
2122

22-
// 2) Save a COPY of the capability value in the user's /storage
23-
let userCapPath = StoragePath(identifier: "TY_UserBetaCap")!
24-
user.storage.save(cap, to: userCapPath)
23+
let copyCap = user.capabilities.storage.issue<&{TidalYieldClosedBeta.IBeta}>(TidalYieldClosedBeta.BetaBadgeStoragePath)
2524

26-
// 3) Optionally publish in /public for scriptable checks
27-
if publishPublic {
28-
let userPubPath = PublicPath(identifier: "TY_Beta")!
29-
user.capabilities.publish<&{TidalYieldClosedBeta.BetaBadge}>(userCapPath, at: userPubPath)
30-
}
25+
user.capabilities.publish(
26+
copyCap,
27+
at: TidalYieldClosedBeta.BetaBadgePublicPath
28+
)
3129
}
3230
}

cadence/transactions/tidal-yield/create_tide.cdc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,12 @@ transaction(strategyIdentifier: String, vaultIdentifier: String, amount: UFix64)
5252
}
5353
self.manager = signer.storage.borrow<&TidalYield.TideManager>(from: TidalYield.TideManagerStoragePath)
5454
?? panic("Signer does not have a TideManager stored at path \(TidalYield.TideManagerStoragePath) - configure and retry")
55-
self.betaRef = signer.storage.borrow<&{TidalYieldClosedBeta.IBeta}>(from: TidalYieldClosedBeta.BetaBadgeStoragePath)
55+
let betaCap = signer.storage.copy<Capability<&{TidalYieldClosedBeta.IBeta}>>(from: TidalYieldClosedBeta.BetaBadgeStoragePath)
5656
?? panic("Signer doesn not have a BetaBadge stored at path \(TidalYieldClosedBeta.BetaBadgeStoragePath) - configure and retry")
57+
58+
self.betaRef = betaCap.borrow()
59+
?? panic("Capability does not contain corret reference")
60+
5761
}
5862

5963
execute {

0 commit comments

Comments
 (0)