Skip to content

Commit 2f4d0d3

Browse files
authored
Merge pull request #81 from OriginProtocol/v155-outstanding-assets
Add outstandingAssets with in-place backfill migration for v155
2 parents 7652b09 + 2aacc53 commit 2f4d0d3

7 files changed

Lines changed: 76 additions & 3 deletions

File tree

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
module.exports = class Data1781633867200 {
2+
name = 'Data1781633867200'
3+
4+
async up(db) {
5+
// In-place upgrade of the live v155 database (continues the existing DB, no re-sync):
6+
// add the per-asset `outstanding_assets` array (in-flight protocol redemptions, aligned
7+
// to Arm.assets) and backfill it from existing data. Adding a NOT NULL column to a
8+
// populated table requires a temporary default; we backfill, then drop the default so the
9+
// schema matches main's squashed migration (where the column is created NOT NULL, no default).
10+
await db.query(`ALTER TABLE "arm_state" ADD COLUMN "outstanding_assets" text array NOT NULL DEFAULT '{}'`)
11+
await db.query(`ALTER TABLE "arm_daily_stat" ADD COLUMN "outstanding_assets" text array NOT NULL DEFAULT '{}'`)
12+
// Every ARM is still pre-upgrade (single base asset, upgradeBlock=null), so
13+
// outstanding_assets = [0, outstandingAssets1]: [0] = liquidity asset (never redeems into
14+
// itself), [1] = the existing outstanding_assets1 scalar. outstanding_assets1 is a numeric
15+
// BigInt; cast to plain-integer text to match the entity's decimal-string array format.
16+
await db.query(`UPDATE "arm_state" SET "outstanding_assets" = ARRAY['0', "outstanding_assets1"::text]`)
17+
await db.query(`UPDATE "arm_daily_stat" SET "outstanding_assets" = ARRAY['0', "outstanding_assets1"::text]`)
18+
await db.query(`ALTER TABLE "arm_state" ALTER COLUMN "outstanding_assets" DROP DEFAULT`)
19+
await db.query(`ALTER TABLE "arm_daily_stat" ALTER COLUMN "outstanding_assets" DROP DEFAULT`)
20+
}
21+
22+
async down(db) {
23+
await db.query(`ALTER TABLE "arm_state" DROP COLUMN "outstanding_assets"`)
24+
await db.query(`ALTER TABLE "arm_daily_stat" DROP COLUMN "outstanding_assets"`)
25+
}
26+
}

schema.graphql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,10 @@ type ArmState @entity {
742742
# assetTotals[0] = assets0 + outstandingAssets1 + marketAssets (all liquidity-denominated value);
743743
# assetTotals[i>0] = balanceOf(asset i). assetTotals[i] x assetRates[i] = value in liquidity terms.
744744
assetTotals: [String!]!
745+
# Per-asset protocol redemptions in-flight (adapter withdrawal queues), aligned to Arm.assets.
746+
# [0] = liquidity asset (never redeems into itself) = 0; [i>0] = pendingRedeemAssets for base
747+
# asset i, liquidity-denominated. Per-asset form of outstandingAssets1 (== sum of [1+]).
748+
outstandingAssets: [String!]!
745749
}
746750

747751
type ArmDailyStat @entity {
@@ -779,6 +783,9 @@ type ArmDailyStat @entity {
779783
assetTotals: [String!]!
780784
# asset->liquidity rate, 1e18-scaled (PRICE_SCALE). [0] = 1e18; pegged base = 1e18.
781785
assetRates: [String!]!
786+
# Per-asset protocol redemptions in-flight, aligned to Arm.assets. [0] = 0 (liquidity asset);
787+
# [i>0] = liquidity-denominated pendingRedeemAssets for base asset i. == sum is outstandingAssets1.
788+
outstandingAssets: [String!]!
782789
}
783790

784791
type ArmAddressYield @entity {

scripts/generate-validations.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,9 @@ const arm = (prefix: string, armAddress: string) => {
466466
totalWithdrawals
467467
totalWithdrawalsClaimed
468468
totalYield
469+
assetBalances
470+
assetTotals
471+
outstandingAssets
469472
}
470473
`),
471474
gql(`
@@ -523,6 +526,10 @@ const arm = (prefix: string, armAddress: string) => {
523526
yield
524527
cumulativeYield
525528
cumulativeFees
529+
assetBalances
530+
assetTotals
531+
assetRates
532+
outstandingAssets
526533
}
527534
`),
528535
gql(`
@@ -559,6 +566,11 @@ const arm = (prefix: string, armAddress: string) => {
559566
address
560567
traderate0
561568
traderate1
569+
asset
570+
buyPrice
571+
sellPrice
572+
buyLiquidityRemaining
573+
sellLiquidityRemaining
562574
}
563575
`),
564576
]
@@ -575,6 +587,11 @@ const arms = () => {
575587
decimals
576588
token0
577589
token1
590+
assets
591+
assetSymbols
592+
assetPegged
593+
assetAdapters
594+
upgradeBlock
578595
}
579596
`)
580597
}

src/model/generated/armDailyStat.model.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,4 +103,7 @@ export class ArmDailyStat {
103103

104104
@StringColumn_({array: true, nullable: false})
105105
assetRates!: (string)[]
106+
107+
@StringColumn_({array: true, nullable: false})
108+
outstandingAssets!: (string)[]
106109
}

src/model/generated/armState.model.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,7 @@ export class ArmState {
7575

7676
@StringColumn_({array: true, nullable: false})
7777
assetTotals!: (string)[]
78+
79+
@StringColumn_({array: true, nullable: false})
80+
outstandingAssets!: (string)[]
7881
}

src/templates/origin-arm/origin-arm.graphql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ type ArmState @entity {
6262
# assetTotals[0] = assets0 + outstandingAssets1 + marketAssets (all liquidity-denominated value);
6363
# assetTotals[i>0] = balanceOf(asset i). assetTotals[i] x assetRates[i] = value in liquidity terms.
6464
assetTotals: [String!]!
65+
# Per-asset protocol redemptions in-flight (adapter withdrawal queues), aligned to Arm.assets.
66+
# [0] = liquidity asset (never redeems into itself) = 0; [i>0] = pendingRedeemAssets for base
67+
# asset i, liquidity-denominated. Per-asset form of outstandingAssets1 (== sum of [1+]).
68+
outstandingAssets: [String!]!
6569
}
6670

6771
type ArmDailyStat @entity {
@@ -99,6 +103,9 @@ type ArmDailyStat @entity {
99103
assetTotals: [String!]!
100104
# asset->liquidity rate, 1e18-scaled (PRICE_SCALE). [0] = 1e18; pegged base = 1e18.
101105
assetRates: [String!]!
106+
# Per-asset protocol redemptions in-flight, aligned to Arm.assets. [0] = 0 (liquidity asset);
107+
# [i>0] = liquidity-denominated pendingRedeemAssets for base asset i. == sum is outstandingAssets1.
108+
outstandingAssets: [String!]!
102109
}
103110

104111
type ArmAddressYield @entity {

src/templates/origin-arm/origin-arm.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -305,14 +305,19 @@ export const createOriginARMProcessors = ({
305305
)
306306
const assets0 = assetBalancesBig[0] ?? 0n // idle liquidity asset (WETH / USDe)
307307
const assets1 = assetBalancesBig[1] ?? 0n // legacy primary base asset
308-
let outstandingAssets1: bigint
308+
// Per-asset protocol redemptions in-flight (adapter withdrawal queues), aligned to
309+
// armEntity.assets. [0] = liquidity asset (never redeems into itself) = 0; [i>0] =
310+
// liquidity-denominated amount pending for base asset i. Multiple base assets can be
311+
// redeeming at once post-upgrade. Legacy scalar outstandingAssets1 == sum of [1+].
312+
let outstandingAssetsBig: bigint[]
309313
if (upgraded) {
310314
// Post-upgrade: pending protocol redemptions live per base asset in liquidity terms.
311315
const multibase = new originMultibaseArmAbi.Contract(ctx, block.header, armAddress)
312316
const configs = await Promise.all(armEntity.assets.slice(1).map((a) => multibase.baseAssetConfigs(a)))
313-
outstandingAssets1 = configs.reduce((acc, c) => acc + c.pendingRedeemAssets, 0n)
317+
outstandingAssetsBig = [0n, ...configs.map((c) => c.pendingRedeemAssets)]
314318
} else {
315-
outstandingAssets1 = await {
319+
// Pre-upgrade: single base asset, one chain-specific withdrawal-queue call.
320+
const single = await {
316321
lido: lidoArmContract.lidoWithdrawalQueueAmount.bind(lidoArmContract),
317322
os: osArmContract.vaultWithdrawalAmount.bind(osArmContract),
318323
etherfi: etherfiArmContract.etherfiWithdrawalQueueAmount.bind(etherfiArmContract),
@@ -321,7 +326,9 @@ export const createOriginARMProcessors = ({
321326
return await ethenaArmContract.liquidityAmountInCooldown()
322327
},
323328
}[armType]()
329+
outstandingAssetsBig = [0n, single]
324330
}
331+
const outstandingAssets1 = outstandingAssetsBig.reduce((acc, b) => acc + b, 0n)
325332
const [feesAccrued, totalAssets, totalAssetsCap, totalSupply, assetsPerShare, activeMarket, claimable] =
326333
await Promise.all([
327334
armContract.feesAccrued(),
@@ -376,6 +383,8 @@ export const createOriginARMProcessors = ({
376383
(assets0 + outstandingAssets1 + marketAssets).toString(),
377384
...assetBalancesBig.slice(1).map((b) => b.toString()),
378385
],
386+
// Per-asset redemptions in-flight, aligned to assets. [0] = 0; sum of [1+] == outstandingAssets1.
387+
outstandingAssets: outstandingAssetsBig.map((b) => b.toString()),
379388
})
380389
armStateEntity.totalYield = calculateTotalYield(armStateEntity)
381390
states.push(armStateEntity)
@@ -754,6 +763,7 @@ export const createOriginARMProcessors = ({
754763
assetBalances: state.assetBalances,
755764
assetTotals: state.assetTotals,
756765
assetRates,
766+
outstandingAssets: state.outstandingAssets,
757767
})
758768
dailyStatsMap.set(currentDayId, armDailyStatEntity)
759769
}

0 commit comments

Comments
 (0)