Skip to content

Commit 4e62174

Browse files
authored
Merge branch 'main' into holyfuchs/FLO-19-dexOraclePriceDeviationInRange
2 parents 4921135 + abe64b3 commit 4e62174

135 files changed

Lines changed: 5317 additions & 1070 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

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

AGENTS.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,9 @@ flow test cadence/tests/interest_accrual_integration_test.cdc --name test_combin
5757
```bash
5858
grep "fun test" cadence/tests/interest_accrual_integration_test.cdc
5959
```
60+
61+
# Cadence Coding Guidelines
62+
63+
- Use string templating, not concatenation: `"Hello \(name)"` not `"Hello ".concat(name)`
64+
- Use `equalWithinVariance` from `test_helpers.cdc` for equality assertions where rounding errors are possible
65+
- Use red-green TDD for bug fixes and extensions to functionality. Tests must use assertions (eg. `Test.assert`) to verify expected behaviour, not logs.

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636

3737
## 🏦 About FlowALP
3838

39-
FlowALP is a decentralized lending and borrowing protocol built on the Flow blockchain. This repository contains the v1 Cadence implementation deployed as the `FlowALPv0` contract. It is token-agnostic (operates over any `FungibleToken.Vault`) and integrates with DeFi Actions for composability.
39+
FlowALP is a decentralized lending and borrowing protocol built on the Flow blockchain. This repository contains the current Cadence implementation deployed as the `FlowALPv0` contract. It is token-agnostic (operates over any `FungibleToken.Vault`) and integrates with DeFi Actions for composability.
4040

4141
### Key Features
4242

@@ -179,7 +179,7 @@ FlowALP/
179179

180180
- `FungibleToken.Vault`: Standard token operations
181181
- `DeFiActions.Sink/Source`: DeFi protocol composability
182-
- Entitlements: `FlowALPv0.EParticipant`, `FlowALPv0.EPosition`, `FlowALPv0.EGovernance`, `FlowALPv0.ERebalance`
182+
- Entitlements: `FlowALPModels.EParticipant`, `FlowALPModels.EPosition`, `FlowALPModels.EGovernance`, `FlowALPModels.ERebalance`
183183

184184
## 🛠️ Development
185185

RebalanceArchitecture.md

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
## Updated Rebalance Architecture
22

3-
This system **rebalances Flow Credit Market (FCM) positions on a schedule**: at a configurable interval, a rebalancer triggers the position’s `rebalance` function. **FCM** holds positions and exposes `rebalance`.
3+
This system **rebalances FlowALP positions on a schedule**: at a configurable interval, a rebalancer triggers the position’s `rebalance` function. **FlowALP** holds positions and exposes `rebalance`.
4+
5+
**Implementation note:** In the current implementation, the FlowALP pool is `FlowALPv0.Pool`.
46

57
A **Rebalancer** when invoked, calls `rebalance` on the position and tries to schedules the next run.
68

79
A **Supervisor** runs on its own schedule (cron) and calls `fixReschedule()` on each registered rebalancer so that transient scheduling failures (e.g. temporary lack of funds) don’t leave rebalancers stuck.
810

911
### Key Principles
1012

11-
* **Isolation:** FCM, Rebalancer, and Supervisor are fully independent.
13+
* **Isolation:** FlowALP, Rebalancer, and Supervisor are fully independent.
1214
* **Least Privilege:** The Rebalancer can *only* trigger the `rebalance` function.
1315
* **Resilience:** The `fixReschedule()` call is idempotent and permissionless, ensuring the system can recover without complex auth (see below).
1416

@@ -39,7 +41,7 @@ There are two rebalancer types; they behave the same for triggering rebalances;
3941
| **User’s control** | Full: config, fixReschedule, withdraw/destroy | Only: fixReschedule by UUID, or delete their RebalancerPaid (stops and removes the rebalancer) |
4042
| **Use case** | User wants full autonomy and to pay their own fees | Admin retains autonomy and pays fees for users (us only) |
4143

42-
**Note:** The Supervisor and the Paid Rebalancer are only intended for use by us; the Standard Rebalancer is for users who self-custody. The bundled `FlowALPSupervisorV1` only tracks **paid** rebalancers (`addPaidRebalancer` / `removePaidRebalancer`). For standard rebalancers, users can call `fixReschedule()` themselves when needed.
44+
**Note:** The Supervisor and the Paid Rebalancer are only intended for use by us; the Standard Rebalancer is for users who self-custody. The bundled `FlowALPSupervisorv1` only tracks **paid** rebalancers (`addPaidRebalancer` / `removePaidRebalancer`). For standard rebalancers, users can call `fixReschedule()` themselves when needed.
4345

4446
### Why calls `fixReschedule()` are necessary
4547

@@ -57,12 +59,12 @@ User creates a position, then creates a **paid** rebalancer (which lives in the
5759
sequenceDiagram
5860
actor admin
5961
actor User
60-
participant FCM
62+
participant FlowALP
6163
participant Paid as Paid Rebalancer Contract
6264
participant Supervisor
6365
Note over admin,Paid: One-time: admin sets defaultRecurringConfig (incl. txFunder)
6466
admin->>Paid: updateDefaultRecurringConfig(config)
65-
User->>FCM: createPosition()
67+
User->>FlowALP: createPosition()
6668
User->>Paid: createPaidRebalancer(positionRebalanceCapability)
6769
Paid-->>User: RebalancerPaid(uuid)
6870
User->>User: save RebalancerPaid
@@ -87,17 +89,17 @@ sequenceDiagram
8789
```mermaid
8890
sequenceDiagram
8991
participant AB1 as AutoRebalancer1
90-
participant FCM
92+
participant FlowALP
9193
participant AB2 as AutoRebalancer2
9294
participant SUP as Supervisor
9395
loop every x min
94-
AB1->>FCM: rebalance()
96+
AB1->>FlowALP: rebalance()
9597
end
9698
loop every y min
97-
AB2->>FCM: rebalance()
99+
AB2->>FlowALP: rebalance()
98100
end
99101
loop every z min
100102
SUP->>AB2: fixReschedule()
101103
SUP->>AB1: fixReschedule()
102104
end
103-
```
105+
```

cadence/contracts/FlowALPEvents.cdc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,11 @@ access(all) contract FlowALPEvents {
141141
)
142142

143143
/// Emitted when the insurance rate for a token is updated by governance.
144-
/// The insurance rate is an annual fraction of debit interest diverted to the insurance fund.
144+
/// The insurance rate is a fee of accrued debit interest diverted to the insurance fund.
145145
///
146146
/// @param poolUUID the UUID of the pool containing the token
147147
/// @param tokenType the type identifier string of the token whose rate changed
148-
/// @param insuranceRate the new annual insurance rate (e.g. 0.001 for 0.1%)
148+
/// @param insuranceRate the new insurance fee (e.g. 0.001 for 0.1%)
149149
access(all) event InsuranceRateUpdated(
150150
poolUUID: UInt64,
151151
tokenType: String,
@@ -167,11 +167,11 @@ access(all) contract FlowALPEvents {
167167
)
168168

169169
/// Emitted when the stability fee rate for a token is updated by governance.
170-
/// The stability fee rate is an annual fraction of debit interest diverted to the stability fund.
170+
/// The stability fee rate is a fee of accrued debit interest diverted to the stability fund.
171171
///
172172
/// @param poolUUID the UUID of the pool containing the token
173173
/// @param tokenType the type identifier string of the token whose rate changed
174-
/// @param stabilityFeeRate the new annual stability fee rate (e.g. 0.05 for 5%)
174+
/// @param stabilityFeeRate the new stability fee (e.g. 0.05 for 5%)
175175
access(all) event StabilityFeeRateUpdated(
176176
poolUUID: UInt64,
177177
tokenType: String,

cadence/contracts/FlowALPInterestRates.cdc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ access(all) contract FlowALPInterestRates {
44
///
55
/// A simple interface to calculate interest rate for a token type.
66
access(all) struct interface InterestCurve {
7-
/// Returns the annual interest rate for the given credit and debit balance, for some token T.
7+
/// Returns the annual nominal interest rate for the given credit and debit balance, for some token T.
88
/// @param creditBalance The credit (deposit) balance of token T
99
/// @param debitBalance The debit (withdrawal) balance of token T
1010
access(all) fun interestRate(creditBalance: UFix128, debitBalance: UFix128): UFix128 {
@@ -19,10 +19,10 @@ access(all) contract FlowALPInterestRates {
1919

2020
/// FixedCurve
2121
///
22-
/// A fixed-rate interest curve implementation that returns a constant yearly interest rate
22+
/// A fixed-rate interest curve implementation that returns a constant nominal yearly interest rate
2323
/// regardless of utilization. This is suitable for stable assets like MOET where predictable
2424
/// rates are desired.
25-
/// @param yearlyRate The fixed yearly interest rate as a UFix128 (e.g., 0.05 for 5% APY)
25+
/// @param yearlyRate The fixed yearly nominal rate as a UFix128 (e.g., 0.05 for a 5% nominal yearly rate)
2626
access(all) struct FixedCurve: InterestCurve {
2727

2828
access(all) let yearlyRate: UFix128
@@ -64,7 +64,7 @@ access(all) contract FlowALPInterestRates {
6464
/// This matches the live TokenState accounting used by FlowALP.
6565
///
6666
/// @param optimalUtilization The target utilization ratio (e.g., 0.80 for 80%)
67-
/// @param baseRate The minimum yearly interest rate (e.g., 0.01 for 1% APY)
67+
/// @param baseRate The minimum yearly nominal rate (e.g., 0.01 for a 1% nominal yearly rate)
6868
/// @param slope1 The total rate increase from 0% to optimal utilization (e.g., 0.04 for 4%)
6969
/// @param slope2 The total rate increase from optimal to 100% utilization (e.g., 0.60 for 60%)
7070
access(all) struct KinkCurve: InterestCurve {

cadence/contracts/FlowALPModels.cdc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1883,6 +1883,9 @@ access(all) contract FlowALPModels {
18831883
/// Returns whether a queued deposit exists for the given token type
18841884
access(all) view fun hasQueuedDeposit(_ type: Type): Bool
18851885

1886+
/// Returns the queued deposit balance for the given token type, or nil if none exists
1887+
access(all) view fun getQueuedDepositBalance(_ type: Type): UFix64?
1888+
18861889
// --- Draw Down Sink ---
18871890

18881891
/// Returns an authorized reference to the draw-down sink, or nil if none is configured.
@@ -2042,6 +2045,14 @@ access(all) contract FlowALPModels {
20422045
return self.queuedDeposits[type] != nil
20432046
}
20442047

2048+
/// Returns the queued deposit balance for the given token type, or nil if none exists.
2049+
access(all) view fun getQueuedDepositBalance(_ type: Type): UFix64? {
2050+
if let queued = &self.queuedDeposits[type] as &{FungibleToken.Vault}? {
2051+
return queued.balance
2052+
}
2053+
return nil
2054+
}
2055+
20452056
// --- Draw Down Sink ---
20462057

20472058
/// Returns an authorized reference to the draw-down sink, or nil if none is configured.
@@ -2114,6 +2125,9 @@ access(all) contract FlowALPModels {
21142125

21152126
/// Rebalances the specified position.
21162127
access(EPosition | ERebalance) fun rebalancePosition(pid: UInt64, force: Bool)
2128+
2129+
/// Queues the position for rebalance/update if its health bounds have changed.
2130+
access(EPosition) fun queuePositionForUpdateIfNecessary(pid: UInt64)
21172131
}
21182132

21192133
/// Factory function to create a new InternalPositionImplv1 resource.

0 commit comments

Comments
 (0)