Skip to content

Commit d29bc11

Browse files
authored
Merge pull request #304 from onflow/revert-247-holyfuchs/FLO-20-createPosition-storage-bloat
Revert "FLO-20: eliminate per-position capability controller bloat"
2 parents 435891a + c1b82c2 commit d29bc11

3 files changed

Lines changed: 57 additions & 60 deletions

File tree

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,3 @@ coverage.json
77
/.pr-body.md
88
/.github/pr_bodies/
99
lcov.info
10-
.flow-fork-cache

cadence/contracts/FlowALPPositionResources.cdc

Lines changed: 56 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,6 @@ import "FlowALPModels"
77

88
access(all) contract FlowALPPositionResources {
99

10-
/// A single authorized Capability to the Pool, shared across all Position resources.
11-
/// Issued once at pool creation time to avoid per-position capability controller bloat.
12-
access(self) var poolCap: Capability<auth(FlowALPModels.EPosition) &{FlowALPModels.PositionPool}>?
13-
14-
/// Sets the contract-level pool capability. Called once by FlowALPv0 when the Pool is created.
15-
access(account) fun setPoolCap(cap: Capability<auth(FlowALPModels.EPosition) &{FlowALPModels.PositionPool}>) {
16-
FlowALPPositionResources.poolCap = cap
17-
}
18-
19-
access(self) fun borrowPool(): auth(FlowALPModels.EPosition) &{FlowALPModels.PositionPool} {
20-
return self.poolCap!.borrow()!
21-
}
22-
2310
/// Position
2411
///
2512
/// A Position is a resource representing ownership of value deposited to the protocol.
@@ -36,13 +23,24 @@ access(all) contract FlowALPPositionResources {
3623
/// The unique ID of the Position used to track deposits and withdrawals to the Pool
3724
access(all) let id: UInt64
3825

39-
init(id: UInt64) {
26+
/// An authorized Capability to the Pool for which this Position was opened.
27+
access(self) let pool: Capability<auth(FlowALPModels.EPosition) &{FlowALPModels.PositionPool}>
28+
29+
init(
30+
id: UInt64,
31+
pool: Capability<auth(FlowALPModels.EPosition) &{FlowALPModels.PositionPool}>
32+
) {
33+
pre {
34+
pool.check():
35+
"Invalid Pool Capability provided - cannot construct Position"
36+
}
4037
self.id = id
38+
self.pool = pool
4139
}
4240

4341
/// Returns the balances (both positive and negative) for all tokens in this position.
4442
access(all) fun getBalances(): [FlowALPModels.PositionBalance] {
45-
let pool = FlowALPPositionResources.borrowPool()
43+
let pool = self.pool.borrow()!
4644
return pool.getPositionDetails(pid: self.id).balances
4745
}
4846

@@ -51,55 +49,55 @@ access(all) contract FlowALPPositionResources {
5149
/// below its min health. If pullFromTopUpSource is false, the calculation will return the balance currently
5250
/// available without topping up the position.
5351
access(all) fun availableBalance(type: Type, pullFromTopUpSource: Bool): UFix64 {
54-
let pool = FlowALPPositionResources.borrowPool()
52+
let pool = self.pool.borrow()!
5553
return pool.availableBalance(pid: self.id, type: type, pullFromTopUpSource: pullFromTopUpSource)
5654
}
5755

5856
/// Returns the current health of the position
5957
access(all) fun getHealth(): UFix128 {
60-
let pool = FlowALPPositionResources.borrowPool()
58+
let pool = self.pool.borrow()!
6159
return pool.positionHealth(pid: self.id)
6260
}
6361

6462
/// Returns the Position's target health (unitless ratio ≥ 1.0)
6563
access(all) fun getTargetHealth(): UFix64 {
66-
let pool = FlowALPPositionResources.borrowPool()
64+
let pool = self.pool.borrow()!
6765
let pos = pool.borrowPosition(pid: self.id)
6866
return FlowALPMath.toUFix64Round(pos.getTargetHealth())
6967
}
7068

7169
/// Sets the target health of the Position
7270
access(FlowALPModels.EPositionAdmin) fun setTargetHealth(targetHealth: UFix64) {
73-
let pool = FlowALPPositionResources.borrowPool()
71+
let pool = self.pool.borrow()!
7472
let pos = pool.borrowPosition(pid: self.id)
7573
pos.setTargetHealth(UFix128(targetHealth))
7674
}
7775

7876
/// Returns the minimum health of the Position
7977
access(all) fun getMinHealth(): UFix64 {
80-
let pool = FlowALPPositionResources.borrowPool()
78+
let pool = self.pool.borrow()!
8179
let pos = pool.borrowPosition(pid: self.id)
8280
return FlowALPMath.toUFix64Round(pos.getMinHealth())
8381
}
8482

8583
/// Sets the minimum health of the Position
8684
access(FlowALPModels.EPositionAdmin) fun setMinHealth(minHealth: UFix64) {
87-
let pool = FlowALPPositionResources.borrowPool()
85+
let pool = self.pool.borrow()!
8886
let pos = pool.borrowPosition(pid: self.id)
8987
pos.setMinHealth(UFix128(minHealth))
9088
pool.queuePositionForUpdateIfNecessary(pid: self.id)
9189
}
9290

9391
/// Returns the maximum health of the Position
9492
access(all) fun getMaxHealth(): UFix64 {
95-
let pool = FlowALPPositionResources.borrowPool()
93+
let pool = self.pool.borrow()!
9694
let pos = pool.borrowPosition(pid: self.id)
9795
return FlowALPMath.toUFix64Round(pos.getMaxHealth())
9896
}
9997

10098
/// Sets the maximum health of the position
10199
access(FlowALPModels.EPositionAdmin) fun setMaxHealth(maxHealth: UFix64) {
102-
let pool = FlowALPPositionResources.borrowPool()
100+
let pool = self.pool.borrow()!
103101
let pos = pool.borrowPosition(pid: self.id)
104102
pos.setMaxHealth(UFix128(maxHealth))
105103
pool.queuePositionForUpdateIfNecessary(pid: self.id)
@@ -127,7 +125,7 @@ access(all) contract FlowALPPositionResources {
127125
from: @{FungibleToken.Vault},
128126
pushToDrawDownSink: Bool
129127
) {
130-
let pool = FlowALPPositionResources.borrowPool()
128+
let pool = self.pool.borrow()!
131129
pool.depositAndPush(
132130
pid: self.id,
133131
from: <-from,
@@ -152,7 +150,7 @@ access(all) contract FlowALPPositionResources {
152150
amount: UFix64,
153151
pullFromTopUpSource: Bool
154152
): @{FungibleToken.Vault} {
155-
let pool = FlowALPPositionResources.borrowPool()
153+
let pool = self.pool.borrow()!
156154
return <- pool.withdrawAndPull(
157155
pid: self.id,
158156
type: type,
@@ -183,8 +181,10 @@ access(all) contract FlowALPPositionResources {
183181
type: Type,
184182
pushToDrawDownSink: Bool
185183
): {DeFiActions.Sink} {
184+
let pool = self.pool.borrow()!
186185
return PositionSink(
187186
id: self.id,
187+
pool: self.pool,
188188
type: type,
189189
pushToDrawDownSink: pushToDrawDownSink
190190
)
@@ -212,8 +212,10 @@ access(all) contract FlowALPPositionResources {
212212
type: Type,
213213
pullFromTopUpSource: Bool
214214
): {DeFiActions.Source} {
215+
let pool = self.pool.borrow()!
215216
return PositionSource(
216217
id: self.id,
218+
pool: self.pool,
217219
type: type,
218220
pullFromTopUpSource: pullFromTopUpSource
219221
)
@@ -230,7 +232,7 @@ access(all) contract FlowALPPositionResources {
230232
///
231233
/// Pass nil to configure the position to not push tokens when the Position exceeds its maximum health.
232234
access(FlowALPModels.EPositionAdmin) fun provideSink(sink: {DeFiActions.Sink}?) {
233-
let pool = FlowALPPositionResources.borrowPool()
235+
let pool = self.pool.borrow()!
234236
pool.lockPosition(self.id)
235237
let pos = pool.borrowPosition(pid: self.id)
236238
pos.setDrawDownSink(sink)
@@ -246,7 +248,7 @@ access(all) contract FlowALPPositionResources {
246248
///
247249
/// Pass nil to configure the position to not pull tokens.
248250
access(FlowALPModels.EPositionAdmin) fun provideSource(source: {DeFiActions.Source}?) {
249-
let pool = FlowALPPositionResources.borrowPool()
251+
let pool = self.pool.borrow()!
250252
pool.lockPosition(self.id)
251253
let pos = pool.borrowPosition(pid: self.id)
252254
pos.setTopUpSource(source)
@@ -262,7 +264,7 @@ access(all) contract FlowALPPositionResources {
262264
/// of either cannot accept/provide sufficient funds for rebalancing, the rebalance will still occur but will
263265
/// not cause the position to reach its target health.
264266
access(FlowALPModels.EPosition | FlowALPModels.ERebalance) fun rebalance(force: Bool) {
265-
let pool = FlowALPPositionResources.borrowPool()
267+
let pool = self.pool.borrow()!
266268
pool.rebalancePosition(pid: self.id, force: force)
267269
}
268270
}
@@ -320,8 +322,11 @@ access(all) contract FlowALPPositionResources {
320322

321323
/// Creates and returns a new Position resource.
322324
/// This remains account-scoped so only the protocol account can mint canonical wrappers.
323-
access(account) fun createPosition(id: UInt64): @Position {
324-
return <- create Position(id: id)
325+
access(account) fun createPosition(
326+
id: UInt64,
327+
pool: Capability<auth(FlowALPModels.EPosition) &{FlowALPModels.PositionPool}>
328+
): @Position {
329+
return <- create Position(id: id, pool: pool)
325330
}
326331

327332
/// Creates and returns a new PositionManager resource
@@ -339,6 +344,9 @@ access(all) contract FlowALPPositionResources {
339344
/// An optional DeFiActions.UniqueIdentifier that identifies this Sink with the DeFiActions stack its a part of
340345
access(contract) var uniqueID: DeFiActions.UniqueIdentifier?
341346

347+
/// An authorized Capability on the Pool for which the related Position is in
348+
access(self) let pool: Capability<auth(FlowALPModels.EPosition) &{FlowALPModels.PositionPool}>
349+
342350
/// The ID of the position in the Pool
343351
access(self) let positionID: UInt64
344352

@@ -351,11 +359,13 @@ access(all) contract FlowALPPositionResources {
351359

352360
init(
353361
id: UInt64,
362+
pool: Capability<auth(FlowALPModels.EPosition) &{FlowALPModels.PositionPool}>,
354363
type: Type,
355364
pushToDrawDownSink: Bool
356365
) {
357366
self.uniqueID = nil
358367
self.positionID = id
368+
self.pool = pool
359369
self.type = type
360370
self.pushToDrawDownSink = pushToDrawDownSink
361371
}
@@ -367,20 +377,18 @@ access(all) contract FlowALPPositionResources {
367377

368378
/// Returns the minimum capacity this Sink can accept as deposits
369379
access(all) fun minimumCapacity(): UFix64 {
370-
return FlowALPPositionResources.poolCap?.check() ?? false ? UFix64.max : 0.0
380+
return self.pool.check() ? UFix64.max : 0.0
371381
}
372382

373383
/// Deposits the funds from the provided Vault reference to the related Position
374384
access(all) fun depositCapacity(from: auth(FungibleToken.Withdraw) &{FungibleToken.Vault}) {
375-
if FlowALPPositionResources.poolCap?.check() != true {
376-
return
385+
if let pool = self.pool.borrow() {
386+
pool.depositAndPush(
387+
pid: self.positionID,
388+
from: <-from.withdraw(amount: from.balance),
389+
pushToDrawDownSink: self.pushToDrawDownSink
390+
)
377391
}
378-
let pool = FlowALPPositionResources.borrowPool()
379-
pool.depositAndPush(
380-
pid: self.positionID,
381-
from: <-from.withdraw(amount: from.balance),
382-
pushToDrawDownSink: self.pushToDrawDownSink
383-
)
384392
}
385393

386394
access(all) fun getComponentInfo(): DeFiActions.ComponentInfo {
@@ -410,6 +418,9 @@ access(all) contract FlowALPPositionResources {
410418
/// An optional DeFiActions.UniqueIdentifier that identifies this Sink with the DeFiActions stack its a part of
411419
access(contract) var uniqueID: DeFiActions.UniqueIdentifier?
412420

421+
/// An authorized Capability on the Pool for which the related Position is in
422+
access(self) let pool: Capability<auth(FlowALPModels.EPosition) &{FlowALPModels.PositionPool}>
423+
413424
/// The ID of the position in the Pool
414425
access(self) let positionID: UInt64
415426

@@ -422,11 +433,13 @@ access(all) contract FlowALPPositionResources {
422433

423434
init(
424435
id: UInt64,
436+
pool: Capability<auth(FlowALPModels.EPosition) &{FlowALPModels.PositionPool}>,
425437
type: Type,
426438
pullFromTopUpSource: Bool
427439
) {
428440
self.uniqueID = nil
429441
self.positionID = id
442+
self.pool = pool
430443
self.type = type
431444
self.pullFromTopUpSource = pullFromTopUpSource
432445
}
@@ -438,11 +451,11 @@ access(all) contract FlowALPPositionResources {
438451

439452
/// Returns the minimum available this Source can provide on withdrawal
440453
access(all) fun minimumAvailable(): UFix64 {
441-
if FlowALPPositionResources.poolCap?.check() != true {
454+
if !self.pool.check() {
442455
return 0.0
443456
}
444457

445-
let pool = FlowALPPositionResources.borrowPool()
458+
let pool = self.pool.borrow()!
446459
return pool.availableBalance(
447460
pid: self.positionID,
448461
type: self.type,
@@ -452,11 +465,11 @@ access(all) contract FlowALPPositionResources {
452465

453466
/// Withdraws up to the max amount as the sourceType Vault
454467
access(FungibleToken.Withdraw) fun withdrawAvailable(maxAmount: UFix64): @{FungibleToken.Vault} {
455-
if FlowALPPositionResources.poolCap?.check() != true {
468+
if !self.pool.check() {
456469
return <- DeFiActionsUtils.getEmptyVault(self.type)
457470
}
458471

459-
let pool = FlowALPPositionResources.borrowPool()
472+
let pool = self.pool.borrow()!
460473
let available = pool.availableBalance(
461474
pid: self.positionID,
462475
type: self.type,
@@ -492,8 +505,4 @@ access(all) contract FlowALPPositionResources {
492505
self.uniqueID = id
493506
}
494507
}
495-
496-
init() {
497-
self.poolCap = nil
498-
}
499508
}

cadence/contracts/FlowALPv0.cdc

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,7 +1052,7 @@ access(all) contract FlowALPv0 {
10521052

10531053
// Create and return the Position resource
10541054

1055-
let position <- FlowALPPositionResources.createPosition(id: id)
1055+
let position <- FlowALPPositionResources.createPosition(id: id, pool: poolCap)
10561056

10571057
self.unlockPosition(id)
10581058
return <-position
@@ -2241,16 +2241,6 @@ access(all) contract FlowALPv0 {
22412241

22422242
/* --- INTERNAL METHODS --- */
22432243

2244-
/// Returns an authorized reference to the contract-managed Pool resource.
2245-
/// Used internally by Position, PositionSink, and PositionSource instead of
2246-
/// issuing per-position storage capabilities.
2247-
access(self) fun _borrowPool(): Capability<auth(FlowALPModels.EPosition) &{FlowALPModels.PositionPool}> {
2248-
let poolCap = FlowALPv0.account.capabilities.storage.issue<auth(FlowALPModels.EPosition) &{FlowALPModels.PositionPool}>(
2249-
FlowALPv0.PoolStoragePath
2250-
)
2251-
return poolCap
2252-
}
2253-
22542244
/// Returns a reference to the contract account's MOET Minter resource
22552245
access(self) view fun _borrowMOETMinter(): &MOET.Minter {
22562246
return self.account.storage.borrow<&MOET.Minter>(from: MOET.AdminStoragePath)
@@ -2272,6 +2262,5 @@ access(all) contract FlowALPv0 {
22722262
to: self.PoolFactoryPath
22732263
)
22742264
let factory = self.account.storage.borrow<&PoolFactory>(from: self.PoolFactoryPath)!
2275-
FlowALPPositionResources.setPoolCap(cap: self._borrowPool())
22762265
}
22772266
}

0 commit comments

Comments
 (0)