diff --git a/db/migrations/1695855931552-Data.js b/db/migrations/1696284606457-Data.js similarity index 97% rename from db/migrations/1695855931552-Data.js rename to db/migrations/1696284606457-Data.js index f27d4e4f..b7f35b73 100644 --- a/db/migrations/1695855931552-Data.js +++ b/db/migrations/1696284606457-Data.js @@ -1,8 +1,8 @@ -module.exports = class Data1695855931552 { - name = 'Data1695855931552' +module.exports = class Data1696284606457 { + name = 'Data1696284606457' async up(db) { - await db.query(`CREATE TABLE "oeth" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "total_supply" numeric NOT NULL, CONSTRAINT "PK_de1d885501070dbd1ab6f8577ba" PRIMARY KEY ("id"))`) + await db.query(`CREATE TABLE "oeth" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "total_supply" numeric NOT NULL, "rebasing_supply" numeric NOT NULL, "non_rebasing_supply" numeric NOT NULL, CONSTRAINT "PK_de1d885501070dbd1ab6f8577ba" PRIMARY KEY ("id"))`) await db.query(`CREATE INDEX "IDX_5b81a67229bac2d68e0dc92cc4" ON "oeth" ("timestamp") `) await db.query(`CREATE INDEX "IDX_408e5f79f83093aa5cf2b0ea32" ON "oeth" ("block_number") `) await db.query(`CREATE TABLE "history" ("id" character varying NOT NULL, "value" numeric NOT NULL, "balance" numeric NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "tx_hash" text NOT NULL, "type" character varying(8) NOT NULL, "address_id" character varying, CONSTRAINT "PK_9384942edf4804b38ca0ee51416" PRIMARY KEY ("id"))`) diff --git a/schema.graphql b/schema.graphql index d8dcea65..443e60d8 100644 --- a/schema.graphql +++ b/schema.graphql @@ -3,6 +3,8 @@ type OETH @entity { timestamp: DateTime! @index blockNumber: Int! @index totalSupply: BigInt! + rebasingSupply: BigInt! + nonRebasingSupply: BigInt! } enum RebasingOption { diff --git a/src/model/generated/oeth.model.ts b/src/model/generated/oeth.model.ts index ee84fcf1..4f2d1ace 100644 --- a/src/model/generated/oeth.model.ts +++ b/src/model/generated/oeth.model.ts @@ -20,4 +20,10 @@ export class OETH { @Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false}) totalSupply!: bigint + + @Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false}) + rebasingSupply!: bigint + + @Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false}) + nonRebasingSupply!: bigint } diff --git a/src/processors/oeth/oeth.ts b/src/processors/oeth/oeth.ts index 4a503d76..65014643 100644 --- a/src/processors/oeth/oeth.ts +++ b/src/processors/oeth/oeth.ts @@ -27,7 +27,7 @@ export const from = 16933090 // https://etherscan.io/tx/0x3b4ece4f5fef04bf7ceaec export const setup = (processor: EvmBatchProcessor) => { processor.addTrace({ - type: ['call', 'delegatecall'], + type: ['call'], callSighash: [ oeth.functions.rebaseOptOut.sighash, oeth.functions.rebaseOptIn.sighash, @@ -121,12 +121,10 @@ const processTransfer = async ( value: dataRaw.value, } + const oethObject = await getLatestOETHObject(ctx, result, block) if (data.from === ADDRESS_ZERO) { - const oethObject = await getLatestOETHObject(ctx, result, block) oethObject.totalSupply += data.value - } - if (data.to === ADDRESS_ZERO) { - const oethObject = await getLatestOETHObject(ctx, result, block) + } else if (data.to === ADDRESS_ZERO) { oethObject.totalSupply -= data.value } @@ -155,12 +153,13 @@ const processTransfer = async ( [addressSub, addressAdd].map(async (address) => { const credits = await token.creditsBalanceOfHighres(address.id) const newBalance = (credits[0] * DECIMALS_18) / credits[1] + const change = newBalance - address.balance result.history.push( new History({ // we can't use {t.id} because it's not unique id: uuidv4(), address: address, - value: newBalance - address.balance, + value: change, balance: newBalance, timestamp: new Date(block.header.timestamp), blockNumber: block.header.height, @@ -176,6 +175,40 @@ const processTransfer = async ( address.balance = newBalance // token balance }), ) + + if ( + addressAdd.rebasingOption === RebasingOption.OptOut && + data.from === ADDRESS_ZERO + ) { + // If it's a mint and minter has opted out of rebasing, + // add to non-rebasing supply + oethObject.nonRebasingSupply += data.value + } else if ( + data.to === ADDRESS_ZERO && + addressSub.rebasingOption === RebasingOption.OptOut + ) { + // If it's a redeem and redeemer has opted out of rebasing, + // subtract non-rebasing supply + oethObject.nonRebasingSupply -= data.value + } else if ( + addressAdd.rebasingOption === RebasingOption.OptOut && + addressSub.rebasingOption === RebasingOption.OptIn + ) { + // If receiver has opted out but sender hasn't, + // Add to non-rebasing supply + oethObject.nonRebasingSupply += data.value + } else if ( + addressAdd.rebasingOption === RebasingOption.OptIn && + addressSub.rebasingOption === RebasingOption.OptOut + ) { + // If sender has opted out but receiver hasn't, + // Subtract non-rebasing supply + oethObject.nonRebasingSupply -= data.value + } + + // Update rebasing supply in all cases + oethObject.rebasingSupply = + oethObject.totalSupply - oethObject.nonRebasingSupply } } @@ -194,6 +227,8 @@ const processTotalSupplyUpdatedHighres = async ( // OETH Object const oethObject = await getLatestOETHObject(ctx, result, block) oethObject.totalSupply = data.totalSupply + oethObject.rebasingSupply = + oethObject.totalSupply - oethObject.nonRebasingSupply if (!result.lastYieldDistributionEvent) { throw new Error('lastYieldDistributionEvent is not set') @@ -266,7 +301,8 @@ const processRebaseOpt = async ( await result.initialize() const timestamp = new Date(block.header.timestamp) const blockNumber = block.header.height - const address = trace.transaction!.from.toLowerCase() + const address = trace.action.from.toLowerCase() + const oethObject = await getLatestOETHObject(ctx, result, block) let owner = result.owners.get(address) if (!owner) { owner = await createAddress(ctx, address, timestamp) @@ -285,10 +321,16 @@ const processRebaseOpt = async ( if (trace.action.sighash === oeth.functions.rebaseOptIn.sighash) { owner.rebasingOption = RebasingOption.OptIn rebaseOption.status = RebasingOption.OptIn + oethObject.nonRebasingSupply -= owner.balance + oethObject.rebasingSupply = + oethObject.totalSupply - oethObject.nonRebasingSupply } if (trace.action.sighash === oeth.functions.rebaseOptOut.sighash) { owner.rebasingOption = RebasingOption.OptOut rebaseOption.status = RebasingOption.OptOut + oethObject.nonRebasingSupply += owner.balance + oethObject.rebasingSupply = + oethObject.totalSupply - oethObject.nonRebasingSupply } } } @@ -313,6 +355,8 @@ const getLatestOETHObject = async ( timestamp: new Date(block.header.timestamp), blockNumber: block.header.height, totalSupply: latest?.totalSupply ?? 0n, + rebasingSupply: latest?.rebasingSupply ?? 0n, + nonRebasingSupply: latest?.nonRebasingSupply ?? 0n, }) result.oeths.push(oethObject) }