From c59a5fbc0ce3603c80e3054b8aa41ec3355e2c4e Mon Sep 17 00:00:00 2001 From: Julien Date: Mon, 23 Sep 2024 10:15:22 +0200 Subject: [PATCH 01/13] feat(public-allocator): add public allocator to the template --- abis/PublicAllocator.json | 579 ++++++++++++++++++++++++++++++++++++++ networks.json | 8 + src/public-allocator.ts | 20 ++ subgraph.yaml | 36 +++ 4 files changed, 643 insertions(+) create mode 100644 abis/PublicAllocator.json create mode 100644 src/public-allocator.ts diff --git a/abis/PublicAllocator.json b/abis/PublicAllocator.json new file mode 100644 index 0000000..36bb4da --- /dev/null +++ b/abis/PublicAllocator.json @@ -0,0 +1,579 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "morpho", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AlreadySet", + "type": "error" + }, + { + "inputs": [], + "name": "DepositMarketInWithdrawals", + "type": "error" + }, + { + "inputs": [], + "name": "EmptyWithdrawals", + "type": "error" + }, + { + "inputs": [], + "name": "InconsistentWithdrawals", + "type": "error" + }, + { + "inputs": [], + "name": "IncorrectFee", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "Id", + "name": "id", + "type": "bytes32" + } + ], + "name": "MarketNotEnabled", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "Id", + "name": "id", + "type": "bytes32" + } + ], + "name": "MaxInflowExceeded", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "Id", + "name": "id", + "type": "bytes32" + } + ], + "name": "MaxOutflowExceeded", + "type": "error" + }, + { + "inputs": [], + "name": "MaxSettableFlowCapExceeded", + "type": "error" + }, + { + "inputs": [], + "name": "NotAdminNorVaultOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "Id", + "name": "id", + "type": "bytes32" + } + ], + "name": "NotEnoughSupply", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "Id", + "name": "id", + "type": "bytes32" + } + ], + "name": "WithdrawZero", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "indexed": true, + "internalType": "Id", + "name": "supplyMarketId", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "suppliedAssets", + "type": "uint256" + } + ], + "name": "PublicReallocateTo", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "indexed": true, + "internalType": "Id", + "name": "id", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "withdrawnAssets", + "type": "uint256" + } + ], + "name": "PublicWithdrawal", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "admin", + "type": "address" + } + ], + "name": "SetAdmin", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "SetFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "components": [ + { + "internalType": "Id", + "name": "id", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "uint128", + "name": "maxIn", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "maxOut", + "type": "uint128" + } + ], + "internalType": "struct FlowCaps", + "name": "caps", + "type": "tuple" + } + ], + "indexed": false, + "internalType": "struct FlowCapsConfig[]", + "name": "config", + "type": "tuple[]" + } + ], + "name": "SetFlowCaps", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "feeRecipient", + "type": "address" + } + ], + "name": "TransferFee", + "type": "event" + }, + { + "inputs": [], + "name": "MORPHO", + "outputs": [ + { + "internalType": "contract IMorpho", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "accruedFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "fee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "Id", + "name": "", + "type": "bytes32" + } + ], + "name": "flowCaps", + "outputs": [ + { + "internalType": "uint128", + "name": "maxIn", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "maxOut", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "components": [ + { + "components": [ + { + "internalType": "address", + "name": "loanToken", + "type": "address" + }, + { + "internalType": "address", + "name": "collateralToken", + "type": "address" + }, + { + "internalType": "address", + "name": "oracle", + "type": "address" + }, + { + "internalType": "address", + "name": "irm", + "type": "address" + }, + { + "internalType": "uint256", + "name": "lltv", + "type": "uint256" + } + ], + "internalType": "struct MarketParams", + "name": "marketParams", + "type": "tuple" + }, + { + "internalType": "uint128", + "name": "amount", + "type": "uint128" + } + ], + "internalType": "struct Withdrawal[]", + "name": "withdrawals", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "address", + "name": "loanToken", + "type": "address" + }, + { + "internalType": "address", + "name": "collateralToken", + "type": "address" + }, + { + "internalType": "address", + "name": "oracle", + "type": "address" + }, + { + "internalType": "address", + "name": "irm", + "type": "address" + }, + { + "internalType": "uint256", + "name": "lltv", + "type": "uint256" + } + ], + "internalType": "struct MarketParams", + "name": "supplyMarketParams", + "type": "tuple" + } + ], + "name": "reallocateTo", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "setAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "internalType": "uint256", + "name": "newFee", + "type": "uint256" + } + ], + "name": "setFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "components": [ + { + "internalType": "Id", + "name": "id", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "uint128", + "name": "maxIn", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "maxOut", + "type": "uint128" + } + ], + "internalType": "struct FlowCaps", + "name": "caps", + "type": "tuple" + } + ], + "internalType": "struct FlowCapsConfig[]", + "name": "config", + "type": "tuple[]" + } + ], + "name": "setFlowCaps", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "internalType": "address payable", + "name": "feeRecipient", + "type": "address" + } + ], + "name": "transferFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/networks.json b/networks.json index 9783836..32b220b 100644 --- a/networks.json +++ b/networks.json @@ -8,6 +8,10 @@ "MetaMorphoFactory": { "address": "0xa9c3d3a366466fa809d1ae982fb2c46e5fc41101", "startBlock": 18925584 + }, + "PublicAllocator": { + "address": "0xfd32fA2ca22c76dD6E550706Ad913FC6CE91c75D", + "startBlock": 19375099 } }, "base": { @@ -19,6 +23,10 @@ "MetaMorphoFactory": { "address": "0xa9c3d3a366466fa809d1ae982fb2c46e5fc41101", "startBlock": 13978134 + }, + "PublicAllocator": { + "address": "0xA090dD1a701408Df1d4d0B85b716c87565f90467", + "startBlock": 13979545 } } } \ No newline at end of file diff --git a/src/public-allocator.ts b/src/public-allocator.ts new file mode 100644 index 0000000..47ec442 --- /dev/null +++ b/src/public-allocator.ts @@ -0,0 +1,20 @@ +import { + PublicReallocateTo, + PublicWithdrawal, + SetAdmin, + SetFee, + SetFlowCaps, + TransferFee, +} from "../generated/PublicAllocator/PublicAllocator"; + +export function handlePublicReallocateTo(event: PublicReallocateTo): void {} + +export function handlePublicWithdrawal(event: PublicWithdrawal): void {} + +export function handleSetAdmin(event: SetAdmin): void {} + +export function handleSetFee(event: SetFee): void {} + +export function handleSetFlowCaps(event: SetFlowCaps): void {} + +export function handleTransferFee(event: TransferFee): void {} diff --git a/subgraph.yaml b/subgraph.yaml index 678f043..a0101ec 100644 --- a/subgraph.yaml +++ b/subgraph.yaml @@ -133,6 +133,42 @@ dataSources: address,string,string,bytes32) handler: handleCreateMetaMorpho file: ./src/meta-morpho-factory.ts + - kind: ethereum + name: PublicAllocator + network: mainnet + source: + address: "0xfd32fA2ca22c76dD6E550706Ad913FC6CE91c75D" + abi: PublicAllocator + startBlock: 19375099 + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - PublicReallocateTo + - PublicWithdrawal + - SetAdmin + - SetFee + - SetFlowCaps + - TransferFee + abis: + - name: PublicAllocator + file: ./abis/PublicAllocator.json + eventHandlers: + - event: PublicReallocateTo(indexed address,indexed address,indexed bytes32,uint256) + handler: handlePublicReallocateTo + - event: PublicWithdrawal(indexed address,indexed address,indexed bytes32,uint256) + handler: handlePublicWithdrawal + - event: SetAdmin(indexed address,indexed address,address) + handler: handleSetAdmin + - event: SetFee(indexed address,indexed address,uint256) + handler: handleSetFee + - event: SetFlowCaps(indexed address,indexed address,(bytes32,(uint128,uint128))[]) + handler: handleSetFlowCaps + - event: TransferFee(indexed address,indexed address,uint256,indexed address) + handler: handleTransferFee + file: ./src/public-allocator.ts + templates: - kind: ethereum name: MetaMorpho From 86f104089de0189542f98356b64980d95966aec2 Mon Sep 17 00:00:00 2001 From: Julien Date: Mon, 23 Sep 2024 10:20:09 +0200 Subject: [PATCH 02/13] feat(public-allocator): create entities --- schema.graphql | 169 +++++++++++++++++++++++++++++++++++++++- src/public-allocator.ts | 48 +++++++++++- 2 files changed, 215 insertions(+), 2 deletions(-) diff --git a/schema.graphql b/schema.graphql index 08f2483..08d57d2 100644 --- a/schema.graphql +++ b/schema.graphql @@ -2047,6 +2047,7 @@ type MetaMorpho @entity { owner: Account! curator: Account allocators: [MetaMorphoAllocator!]! @derivedFrom(field: "metaMorpho") + hasPublicAllocator: Boolean! guardian: Account timelock: BigInt! @@ -2082,6 +2083,12 @@ type MetaMorpho @entity { deposits: [MetaMorphoDeposit!]! @derivedFrom(field: "metaMorpho") withdraws: [MetaMorphoWithdraw!]! @derivedFrom(field: "metaMorpho") transfers: [MetaMorphoTransfer!]! @derivedFrom(field: "metaMorpho") + + publicAllocatorMarkets: [MetaMorphoPublicAllocatorMarket!]! @derivedFrom(field: "metaMorpho") + marketFlowCapsChanges: [MarketFlowCapsSet!]! @derivedFrom(field: "metaMorpho") + publicAllocatorWithdrawals: [PublicAllocatorWithdrawalEvent!]! @derivedFrom(field: "metaMorpho") + publicAllocatorReallocationToEvent: [PublicAllocatorReallocationToEvent!]! @derivedFrom(field: "metaMorpho") + publicAllocatorSetFlowCapsEvent: [MarketFlowCapsSet!]! @derivedFrom(field: "metaMorpho") } type FeeRecipient @entity { id: Bytes! @@ -2103,6 +2110,9 @@ type MetaMorphoMarket @entity { isInSupplyQueue: Boolean! isInWithdrawQueue: Boolean! pendingCaps: [PendingCap!]! @derivedFrom(field: "metaMorphoMarket") + + publicAllocatorMarket: MetaMorphoPublicAllocatorMarket @derivedFrom(field: "market") + # TODO: add position } @@ -2177,6 +2187,7 @@ type MetaMorphoAllocator @entity { account: Account! metaMorpho: MetaMorpho! isCurrentAllocator: Boolean! + isPublicAllocator: Boolean! } @@ -2373,4 +2384,160 @@ type MetaMorphoTransfer @entity(immutable: true) { rate: InterestRate! -} \ No newline at end of file +} + +type MetaMorphoPublicAllocator @entity(immutable: true) { + id: Bytes! + + metaMorpho: MetaMorpho + + allocator: MetaMorphoAllocator + + fee: BigInt! + + admin: Account! + +} + +type MetaMorphoPublicAllocatorMarket @entity(immutable: true) { + id: Bytes! + + metaMorpho: MetaMorpho + market: MetaMorphoMarket + + flowCapIn: BigInt! + flowCapOut: BigInt! + + setFlowCapsEvents: [SetFlowCapsEvent!]! @derivedFrom(field: "market") + reallocationToEvents: [PublicAllocatorReallocationToEvent!]! @derivedFrom(field: "market") + withdrawalEvents: [PublicAllocatorWithdrawalEvent!]! @derivedFrom(field: "market") + flowCapsChanges: [MarketFlowCapsSet!]! @derivedFrom(field: "market") + +} + +type SetFlowCapsEvent implements Event @entity(immutable: true) @transaction { + + " { Transaction hash }{ Log index } " + id: Bytes! + + " Transaction hash of the transaction that emitted this event " + hash: Bytes! + + " Nonce of the transaction that emitted this event " + nonce: BigInt! + + " Event log index. For transactions that don't emit event, create arbitrary index starting from 0 " + logIndex: Int! + + " Price of gas in this transaction " + gasPrice: BigInt + + " Gas used in this transaction. (Optional because not every chain will support this) " + gasUsed: BigInt + + " Gas limit of this transaction. e.g. the amount of gas the sender will pay " + gasLimit: BigInt + + " Block number of this event " + blockNumber: BigInt! + + " Timestamp of this event " + timestamp: BigInt! + + + metaMorpho: MetaMorpho + + market: MetaMorphoPublicAllocatorMarket + + flowCaps: [MarketFlowCapsSet!]! @derivedFrom(field: "setFlowCapsEvent") +} + +type PublicAllocatorReallocationToEvent implements Event @entity(immutable: true) @transaction { + + " { Transaction hash }{ Log index } " + id: Bytes! + + " Transaction hash of the transaction that emitted this event " + hash: Bytes! + + " Nonce of the transaction that emitted this event " + nonce: BigInt! + + " Event log index. For transactions that don't emit event, create arbitrary index starting from 0 " + logIndex: Int! + + " Price of gas in this transaction " + gasPrice: BigInt + + " Gas used in this transaction. (Optional because not every chain will support this) " + gasUsed: BigInt + + " Gas limit of this transaction. e.g. the amount of gas the sender will pay " + gasLimit: BigInt + + " Block number of this event " + blockNumber: BigInt! + + " Timestamp of this event " + timestamp: BigInt! + + metaMorpho: MetaMorpho + + market: MetaMorphoPublicAllocatorMarket +} + +type PublicAllocatorWithdrawalEvent implements Event @entity(immutable: true) @transaction { + + " { Transaction hash }{ Log index } " + id: Bytes! + + " Transaction hash of the transaction that emitted this event " + hash: Bytes! + + " Nonce of the transaction that emitted this event " + nonce: BigInt! + + " Event log index. For transactions that don't emit event, create arbitrary index starting from 0 " + logIndex: Int! + + " Price of gas in this transaction " + gasPrice: BigInt + + " Gas used in this transaction. (Optional because not every chain will support this) " + gasUsed: BigInt + + " Gas limit of this transaction. e.g. the amount of gas the sender will pay " + gasLimit: BigInt + + " Block number of this event " + blockNumber: BigInt! + + " Timestamp of this event " + timestamp: BigInt! + + metaMorpho: MetaMorpho + + market: MetaMorphoPublicAllocatorMarket + + flowCaps: [MarketFlowCapsSet!]! @derivedFrom(field: "publicWithdrawalEvent") +} + +type MarketFlowCapsSet @entity(immutable: true) { + id: Bytes! + + metaMorpho: MetaMorpho + + market: MetaMorphoPublicAllocatorMarket + + prevFlowCapIn: BigInt! + flowCapIn: BigInt! + + prevFlowCapOut: BigInt! + flowCapOut: BigInt! + + + setFlowCapsEvent: SetFlowCapsEvent + publicReallocationEvent: PublicAllocatorReallocationToEvent + publicWithdrawalEvent: PublicAllocatorWithdrawalEvent + +} diff --git a/src/public-allocator.ts b/src/public-allocator.ts index 47ec442..7bf0bb4 100644 --- a/src/public-allocator.ts +++ b/src/public-allocator.ts @@ -1,3 +1,5 @@ +import { BigInt } from "@graphprotocol/graph-ts"; + import { PublicReallocateTo, PublicWithdrawal, @@ -7,7 +9,51 @@ import { TransferFee, } from "../generated/PublicAllocator/PublicAllocator"; -export function handlePublicReallocateTo(event: PublicReallocateTo): void {} +export function handlePublicReallocateTo(event: PublicReallocateTo): void { + // Entities can be loaded from the store using a string ID; this ID + // needs to be unique across all entities of the same type + let entity = ExampleEntity.load(event.transaction.from); + + // Entities only exist after they have been saved to the store; + // `null` checks allow to create entities on demand + if (!entity) { + entity = new ExampleEntity(event.transaction.from); + + // Entity fields can be set using simple assignments + entity.count = BigInt.fromI32(0); + } + + // BigInt and BigDecimal math are supported + entity.count = entity.count + BigInt.fromI32(1); + + // Entity fields can be set based on event parameters + entity.sender = event.params.sender; + entity.vault = event.params.vault; + + // Entities can be written to the store with `.save()` + entity.save(); + + // Note: If a handler doesn't require existing field values, it is faster + // _not_ to load the entity from the store. Instead, create it fresh with + // `new Entity(...)`, set the fields that should be updated and save the + // entity back to the store. Fields that were not set or unset remain + // unchanged, allowing for partial updates to be applied. + + // It is also possible to access smart contracts from mappings. For + // example, the contract that has emitted the event can be connected to + // with: + // + // let contract = Contract.bind(event.address) + // + // The following functions can then be called on this contract to access + // state variables and other data: + // + // - contract.MORPHO(...) + // - contract.accruedFee(...) + // - contract.admin(...) + // - contract.fee(...) + // - contract.flowCaps(...) +} export function handlePublicWithdrawal(event: PublicWithdrawal): void {} From 2b5e1bfede1f7d3e3dac18bad53a2811a16b8f51 Mon Sep 17 00:00:00 2001 From: Julien Date: Mon, 23 Sep 2024 10:27:55 +0200 Subject: [PATCH 03/13] feat(public-allocator): check if a metaMorpho has a public allocator --- src/meta-morpho.ts | 21 +++++++++++++++- src/public-allocator.ts | 48 +----------------------------------- src/utils/publicAllocator.ts | 13 ++++++++++ 3 files changed, 34 insertions(+), 48 deletions(-) create mode 100644 src/utils/publicAllocator.ts diff --git a/src/meta-morpho.ts b/src/meta-morpho.ts index 3eed129..55e53e1 100644 --- a/src/meta-morpho.ts +++ b/src/meta-morpho.ts @@ -1,4 +1,10 @@ -import { Address, BigInt, Bytes, log } from "@graphprotocol/graph-ts"; +import { + Address, + BigInt, + Bytes, + log, + dataSource, +} from "@graphprotocol/graph-ts"; import { AllocatorSet, @@ -58,6 +64,7 @@ import { } from "./sdk/metamorpho"; import { TokenManager } from "./sdk/token"; import { toMetaMorphoAssetsUp } from "./utils/metaMorphoUtils"; +import { publicAllocatorPerNetwork } from "./utils/publicAllocator"; import { cloneRate } from "./utils/rate"; export function handleSubmitMarketRemoval( @@ -394,8 +401,19 @@ export function handleSetIsAllocator(event: SetIsAllocatorEvent): void { allocator.metaMorpho = mm.id; } allocator.isCurrentAllocator = event.params.isAllocator; + allocator.isPublicAllocator = publicAllocatorPerNetwork( + dataSource.network() + ).equals(event.params.allocator); + allocator.save(); + if (allocator.isPublicAllocator && event.params.isAllocator) { + mm.hasPublicAllocator = true; + } else { + mm.hasPublicAllocator = false; + } + mm.save(); + const allocatorSet = new AllocatorSet( event.transaction.hash.concat(Bytes.fromI32(event.logIndex.toI32())) ); @@ -420,6 +438,7 @@ export function handleSetSkimRecipient(event: SetSkimRecipientEvent): void {} export function handleSetSupplyQueue(event: SetSupplyQueueEvent): void { // Supply queue on subgraph is a list of MetaMorphoMarket ids, not Market ids. const mm = loadMetaMorpho(event.address); + const newSupplyQueue: Array = []; const addedMarkets: Array = []; const seen = new Map(); diff --git a/src/public-allocator.ts b/src/public-allocator.ts index 7bf0bb4..47ec442 100644 --- a/src/public-allocator.ts +++ b/src/public-allocator.ts @@ -1,5 +1,3 @@ -import { BigInt } from "@graphprotocol/graph-ts"; - import { PublicReallocateTo, PublicWithdrawal, @@ -9,51 +7,7 @@ import { TransferFee, } from "../generated/PublicAllocator/PublicAllocator"; -export function handlePublicReallocateTo(event: PublicReallocateTo): void { - // Entities can be loaded from the store using a string ID; this ID - // needs to be unique across all entities of the same type - let entity = ExampleEntity.load(event.transaction.from); - - // Entities only exist after they have been saved to the store; - // `null` checks allow to create entities on demand - if (!entity) { - entity = new ExampleEntity(event.transaction.from); - - // Entity fields can be set using simple assignments - entity.count = BigInt.fromI32(0); - } - - // BigInt and BigDecimal math are supported - entity.count = entity.count + BigInt.fromI32(1); - - // Entity fields can be set based on event parameters - entity.sender = event.params.sender; - entity.vault = event.params.vault; - - // Entities can be written to the store with `.save()` - entity.save(); - - // Note: If a handler doesn't require existing field values, it is faster - // _not_ to load the entity from the store. Instead, create it fresh with - // `new Entity(...)`, set the fields that should be updated and save the - // entity back to the store. Fields that were not set or unset remain - // unchanged, allowing for partial updates to be applied. - - // It is also possible to access smart contracts from mappings. For - // example, the contract that has emitted the event can be connected to - // with: - // - // let contract = Contract.bind(event.address) - // - // The following functions can then be called on this contract to access - // state variables and other data: - // - // - contract.MORPHO(...) - // - contract.accruedFee(...) - // - contract.admin(...) - // - contract.fee(...) - // - contract.flowCaps(...) -} +export function handlePublicReallocateTo(event: PublicReallocateTo): void {} export function handlePublicWithdrawal(event: PublicWithdrawal): void {} diff --git a/src/utils/publicAllocator.ts b/src/utils/publicAllocator.ts new file mode 100644 index 0000000..86746af --- /dev/null +++ b/src/utils/publicAllocator.ts @@ -0,0 +1,13 @@ +import { Address, log } from "@graphprotocol/graph-ts"; + +export function publicAllocatorPerNetwork(network: string): Address { + if (network === "mainnet") { + return Address.fromString("0xfd32fA2ca22c76dD6E550706Ad913FC6CE91c75D"); + } + if (network === "base") { + return Address.fromString("0xA090dD1a701408Df1d4d0B85b716c87565f90467"); + } + + log.critical("No public allocator for network: {}", [network]); + return Address.zero(); +} From ab63dfea78906a01775090e1535495a05b412b33 Mon Sep 17 00:00:00 2001 From: Julien Date: Mon, 23 Sep 2024 11:12:47 +0200 Subject: [PATCH 04/13] feat(public-allocator): handle public reallocations --- schema.graphql | 41 +++++--- src/meta-morpho.ts | 22 ++-- src/public-allocator.ts | 191 +++++++++++++++++++++++++++++++++-- src/utils/publicAllocator.ts | 5 +- subgraph.yaml | 7 +- 5 files changed, 228 insertions(+), 38 deletions(-) diff --git a/schema.graphql b/schema.graphql index 08d57d2..c115816 100644 --- a/schema.graphql +++ b/schema.graphql @@ -2084,11 +2084,8 @@ type MetaMorpho @entity { withdraws: [MetaMorphoWithdraw!]! @derivedFrom(field: "metaMorpho") transfers: [MetaMorphoTransfer!]! @derivedFrom(field: "metaMorpho") - publicAllocatorMarkets: [MetaMorphoPublicAllocatorMarket!]! @derivedFrom(field: "metaMorpho") - marketFlowCapsChanges: [MarketFlowCapsSet!]! @derivedFrom(field: "metaMorpho") - publicAllocatorWithdrawals: [PublicAllocatorWithdrawalEvent!]! @derivedFrom(field: "metaMorpho") - publicAllocatorReallocationToEvent: [PublicAllocatorReallocationToEvent!]! @derivedFrom(field: "metaMorpho") - publicAllocatorSetFlowCapsEvent: [MarketFlowCapsSet!]! @derivedFrom(field: "metaMorpho") + publicAllocator: MetaMorphoPublicAllocator @derivedFrom(field: "metaMorpho") + } type FeeRecipient @entity { id: Bytes! @@ -2188,6 +2185,8 @@ type MetaMorphoAllocator @entity { metaMorpho: MetaMorpho! isCurrentAllocator: Boolean! isPublicAllocator: Boolean! + + publicAllocatorConfig: MetaMorphoPublicAllocator @derivedFrom(field: "allocator") } @@ -2389,21 +2388,27 @@ type MetaMorphoTransfer @entity(immutable: true) { type MetaMorphoPublicAllocator @entity(immutable: true) { id: Bytes! - metaMorpho: MetaMorpho + metaMorpho: MetaMorpho! allocator: MetaMorphoAllocator fee: BigInt! - admin: Account! + admin: Account + + markets: [MetaMorphoPublicAllocatorMarket!]! @derivedFrom(field: "metaMorpho") + setFlowCapsEvents: [SetFlowCapsEvent!]! @derivedFrom(field: "metaMorpho") + reallocationToEvents: [PublicAllocatorReallocationToEvent!]! @derivedFrom(field: "metaMorpho") + withdrawalEvents: [PublicAllocatorWithdrawalEvent!]! @derivedFrom(field: "metaMorpho") + flowCapsChanges: [MarketFlowCapsSet!]! @derivedFrom(field: "metaMorpho") } type MetaMorphoPublicAllocatorMarket @entity(immutable: true) { id: Bytes! - metaMorpho: MetaMorpho - market: MetaMorphoMarket + metaMorpho: MetaMorphoPublicAllocator! + market: MetaMorphoMarket! flowCapIn: BigInt! flowCapOut: BigInt! @@ -2445,9 +2450,9 @@ type SetFlowCapsEvent implements Event @entity(immutable: true) @transaction { timestamp: BigInt! - metaMorpho: MetaMorpho + metaMorpho: MetaMorphoPublicAllocator! - market: MetaMorphoPublicAllocatorMarket + market: MetaMorphoPublicAllocatorMarket! flowCaps: [MarketFlowCapsSet!]! @derivedFrom(field: "setFlowCapsEvent") } @@ -2481,9 +2486,11 @@ type PublicAllocatorReallocationToEvent implements Event @entity(immutable: true " Timestamp of this event " timestamp: BigInt! - metaMorpho: MetaMorpho + metaMorpho: MetaMorphoPublicAllocator! + + market: MetaMorphoPublicAllocatorMarket! - market: MetaMorphoPublicAllocatorMarket + suppliedAssets: BigInt! } type PublicAllocatorWithdrawalEvent implements Event @entity(immutable: true) @transaction { @@ -2515,19 +2522,21 @@ type PublicAllocatorWithdrawalEvent implements Event @entity(immutable: true) @t " Timestamp of this event " timestamp: BigInt! - metaMorpho: MetaMorpho + metaMorpho: MetaMorphoPublicAllocator market: MetaMorphoPublicAllocatorMarket + withdrawnAssets: BigInt! + flowCaps: [MarketFlowCapsSet!]! @derivedFrom(field: "publicWithdrawalEvent") } type MarketFlowCapsSet @entity(immutable: true) { id: Bytes! - metaMorpho: MetaMorpho + metaMorpho: MetaMorphoPublicAllocator! - market: MetaMorphoPublicAllocatorMarket + market: MetaMorphoPublicAllocatorMarket! prevFlowCapIn: BigInt! flowCapIn: BigInt! diff --git a/src/meta-morpho.ts b/src/meta-morpho.ts index 55e53e1..63d9ea8 100644 --- a/src/meta-morpho.ts +++ b/src/meta-morpho.ts @@ -1,10 +1,4 @@ -import { - Address, - BigInt, - Bytes, - log, - dataSource, -} from "@graphprotocol/graph-ts"; +import { Address, BigInt, Bytes, log } from "@graphprotocol/graph-ts"; import { AllocatorSet, @@ -53,6 +47,7 @@ import { ReallocateWithdraw as ReallocateWithdrawEvent, } from "../generated/templates/MetaMorpho/MetaMorpho"; +import { loadPublicAllocatorVault } from "./public-allocator"; import { AccountManager } from "./sdk/account"; import { loadMetaMorpho, @@ -64,7 +59,7 @@ import { } from "./sdk/metamorpho"; import { TokenManager } from "./sdk/token"; import { toMetaMorphoAssetsUp } from "./utils/metaMorphoUtils"; -import { publicAllocatorPerNetwork } from "./utils/publicAllocator"; +import { getPublicAllocatorAddress } from "./utils/publicAllocator"; import { cloneRate } from "./utils/rate"; export function handleSubmitMarketRemoval( @@ -401,14 +396,19 @@ export function handleSetIsAllocator(event: SetIsAllocatorEvent): void { allocator.metaMorpho = mm.id; } allocator.isCurrentAllocator = event.params.isAllocator; - allocator.isPublicAllocator = publicAllocatorPerNetwork( - dataSource.network() - ).equals(event.params.allocator); + allocator.isPublicAllocator = getPublicAllocatorAddress().equals( + event.params.allocator + ); allocator.save(); if (allocator.isPublicAllocator && event.params.isAllocator) { mm.hasPublicAllocator = true; + + // Update the public allocator vault. It can be created before the allocator is set, so we need to update it here. + const publicAllocatorVault = loadPublicAllocatorVault(event.address); + publicAllocatorVault.allocator = allocator.id; + publicAllocatorVault.save(); } else { mm.hasPublicAllocator = false; } diff --git a/src/public-allocator.ts b/src/public-allocator.ts index 47ec442..47c1bf4 100644 --- a/src/public-allocator.ts +++ b/src/public-allocator.ts @@ -1,3 +1,5 @@ +import { Address, BigInt, Bytes } from "@graphprotocol/graph-ts"; + import { PublicReallocateTo, PublicWithdrawal, @@ -6,15 +8,192 @@ import { SetFlowCaps, TransferFee, } from "../generated/PublicAllocator/PublicAllocator"; +import { + MarketFlowCapsSet, + MetaMorpho, + MetaMorphoAllocator, + MetaMorphoPublicAllocator, + MetaMorphoPublicAllocatorMarket, + PublicAllocatorReallocationToEvent, + PublicAllocatorWithdrawalEvent, +} from "../generated/schema"; + +import { loadMetaMorpho, loadMetaMorphoMarket } from "./sdk/metamorpho"; +import { getPublicAllocatorAddress } from "./utils/publicAllocator"; + +export function loadPublicAllocatorVault( + metaMorpho: Address +): MetaMorphoPublicAllocator { + const id = getPublicAllocatorAddress().concat(metaMorpho); + + let pa = MetaMorphoPublicAllocator.load(id); + + if (!pa) { + pa = new MetaMorphoPublicAllocator(id); + + const mmAllocator = MetaMorphoAllocator.load(id); + if (mmAllocator) { + // a vault owner can set flow caps before having set a public allocator. + // in this case, allocator is added dynamically. + pa.allocator = mmAllocator.id; + } + const mm = loadMetaMorpho(metaMorpho); + pa.metaMorpho = mm.id; + + pa.fee = BigInt.zero(); + pa.save(); + } + return pa; +} + +export function loadPublicAllocatorMarket( + metaMorpho: Address, + market: Bytes +): MetaMorphoPublicAllocatorMarket { + const id = metaMorpho.concat(market); + let paMarket = MetaMorphoPublicAllocatorMarket.load(id); + + if (!paMarket) { + paMarket = new MetaMorphoPublicAllocatorMarket(id); + + const mmMarket = loadMetaMorphoMarket(metaMorpho, market); + paMarket.market = mmMarket.id; + + const paVault = loadPublicAllocatorVault(metaMorpho); + paMarket.metaMorpho = paVault.id; + + paMarket.flowCapIn = BigInt.zero(); + paMarket.flowCapOut = BigInt.zero(); + + paMarket.save(); + } + return paMarket; +} + +/** + * Public allocator can be defined for any address, even if its not a vault. + * The indexer supports only metaMorpho created through the factory. + * These vaults cannot have a config defined before creation, because of the msg.sender === vault.owner() check. + * @param address the address of the vault + */ +function metaMorphoExists(address: Address): boolean { + const mm = MetaMorpho.load(address); + return mm !== null; +} + +export function handlePublicReallocateTo(event: PublicReallocateTo): void { + if (!metaMorphoExists(event.params.vault)) { + return; + } + + const paMarket = loadPublicAllocatorMarket( + event.params.vault, + event.params.supplyMarketId + ); + const newFlowCapIn = paMarket.flowCapIn.minus(event.params.suppliedAssets); + + const eventId = event.transaction.hash.concat( + Bytes.fromI32(event.logIndex.toI32()) + ); + + const marketFlowCapsSet = new MarketFlowCapsSet(eventId); + marketFlowCapsSet.metaMorpho = paMarket.metaMorpho; + marketFlowCapsSet.market = paMarket.market; + + marketFlowCapsSet.prevFlowCapIn = paMarket.flowCapIn; + marketFlowCapsSet.flowCapIn = newFlowCapIn; + + marketFlowCapsSet.prevFlowCapOut = paMarket.flowCapOut; + marketFlowCapsSet.flowCapOut = paMarket.flowCapOut; + + const reallocateToEvent = new PublicAllocatorReallocationToEvent(eventId); + + reallocateToEvent.hash = event.transaction.hash; + reallocateToEvent.nonce = event.transaction.nonce; + reallocateToEvent.logIndex = event.logIndex.toI32(); + reallocateToEvent.gasPrice = event.transaction.gasPrice; + reallocateToEvent.gasUsed = event.receipt ? event.receipt!.gasUsed : null; + reallocateToEvent.gasLimit = event.transaction.gasLimit; + reallocateToEvent.blockNumber = event.block.number; + reallocateToEvent.timestamp = event.block.timestamp; + reallocateToEvent.metaMorpho = paMarket.metaMorpho; + reallocateToEvent.market = paMarket.id; + reallocateToEvent.suppliedAssets = event.params.suppliedAssets; + reallocateToEvent.save(); + + marketFlowCapsSet.publicReallocationEvent = reallocateToEvent.id; + marketFlowCapsSet.save(); + paMarket.flowCapIn = newFlowCapIn; + paMarket.save(); +} + +export function handlePublicWithdrawal(event: PublicWithdrawal): void { + if (!metaMorphoExists(event.params.vault)) { + return; + } + + const paMarket = loadPublicAllocatorMarket( + event.params.vault, + event.params.id + ); + const newFlowCapOut = paMarket.flowCapIn.minus(event.params.withdrawnAssets); + + const eventId = event.transaction.hash.concat( + Bytes.fromI32(event.logIndex.toI32()) + ); + + const marketFlowCapsSet = new MarketFlowCapsSet(eventId); + marketFlowCapsSet.metaMorpho = paMarket.metaMorpho; + marketFlowCapsSet.market = paMarket.market; + + marketFlowCapsSet.prevFlowCapIn = paMarket.flowCapIn; + marketFlowCapsSet.flowCapIn = paMarket.flowCapIn; + + marketFlowCapsSet.prevFlowCapOut = paMarket.flowCapOut; + marketFlowCapsSet.flowCapOut = newFlowCapOut; + + const withdrawalEvent = new PublicAllocatorWithdrawalEvent(eventId); -export function handlePublicReallocateTo(event: PublicReallocateTo): void {} + withdrawalEvent.hash = event.transaction.hash; + withdrawalEvent.nonce = event.transaction.nonce; + withdrawalEvent.logIndex = event.logIndex.toI32(); + withdrawalEvent.gasPrice = event.transaction.gasPrice; + withdrawalEvent.gasUsed = event.receipt ? event.receipt!.gasUsed : null; + withdrawalEvent.gasLimit = event.transaction.gasLimit; + withdrawalEvent.blockNumber = event.block.number; + withdrawalEvent.timestamp = event.block.timestamp; + withdrawalEvent.metaMorpho = paMarket.metaMorpho; + withdrawalEvent.market = paMarket.id; + withdrawalEvent.withdrawnAssets = event.params.withdrawnAssets; + withdrawalEvent.save(); -export function handlePublicWithdrawal(event: PublicWithdrawal): void {} + marketFlowCapsSet.publicWithdrawalEvent = withdrawalEvent.id; + marketFlowCapsSet.save(); + paMarket.flowCapOut = newFlowCapOut; + paMarket.save(); +} -export function handleSetAdmin(event: SetAdmin): void {} +export function handleSetAdmin(event: SetAdmin): void { + if (!metaMorphoExists(event.params.vault)) { + return; + } +} -export function handleSetFee(event: SetFee): void {} +export function handleSetFee(event: SetFee): void { + if (!metaMorphoExists(event.params.vault)) { + return; + } +} -export function handleSetFlowCaps(event: SetFlowCaps): void {} +export function handleSetFlowCaps(event: SetFlowCaps): void { + if (!metaMorphoExists(event.params.vault)) { + return; + } + const mm = loadMetaMorpho(event.params.vault); +} -export function handleTransferFee(event: TransferFee): void {} +export function handleTransferFee(event: TransferFee): void { + if (!metaMorphoExists(event.params.vault)) { + return; + } +} diff --git a/src/utils/publicAllocator.ts b/src/utils/publicAllocator.ts index 86746af..35c7d1a 100644 --- a/src/utils/publicAllocator.ts +++ b/src/utils/publicAllocator.ts @@ -1,6 +1,7 @@ -import { Address, log } from "@graphprotocol/graph-ts"; +import { Address, dataSource, log } from "@graphprotocol/graph-ts"; -export function publicAllocatorPerNetwork(network: string): Address { +export function getPublicAllocatorAddress(): Address { + const network = dataSource.network(); if (network === "mainnet") { return Address.fromString("0xfd32fA2ca22c76dD6E550706Ad913FC6CE91c75D"); } diff --git a/subgraph.yaml b/subgraph.yaml index a0101ec..ff02f9d 100644 --- a/subgraph.yaml +++ b/subgraph.yaml @@ -155,7 +155,8 @@ dataSources: - name: PublicAllocator file: ./abis/PublicAllocator.json eventHandlers: - - event: PublicReallocateTo(indexed address,indexed address,indexed bytes32,uint256) + - event: PublicReallocateTo(indexed address,indexed address,indexed + bytes32,uint256) handler: handlePublicReallocateTo - event: PublicWithdrawal(indexed address,indexed address,indexed bytes32,uint256) handler: handlePublicWithdrawal @@ -163,12 +164,12 @@ dataSources: handler: handleSetAdmin - event: SetFee(indexed address,indexed address,uint256) handler: handleSetFee - - event: SetFlowCaps(indexed address,indexed address,(bytes32,(uint128,uint128))[]) + - event: SetFlowCaps(indexed address,indexed + address,(bytes32,(uint128,uint128))[]) handler: handleSetFlowCaps - event: TransferFee(indexed address,indexed address,uint256,indexed address) handler: handleTransferFee file: ./src/public-allocator.ts - templates: - kind: ethereum name: MetaMorpho From 0507ed14241d5a4d4ceacf7a025133bc8d476bda Mon Sep 17 00:00:00 2001 From: Julien Date: Mon, 23 Sep 2024 11:18:15 +0200 Subject: [PATCH 05/13] feat(public-allocator): handle pa fees --- schema.graphql | 5 +++++ src/public-allocator.ts | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/schema.graphql b/schema.graphql index c115816..6399b0d 100644 --- a/schema.graphql +++ b/schema.graphql @@ -1368,6 +1368,8 @@ type Account @entity @regularPolling { metaMorphoTransferFrom: [MetaMorphoTransfer!]! @derivedFrom(field: "from") metaMorphoTransferTo: [MetaMorphoTransfer!]! @derivedFrom(field: "to") + publicAllocatorAdmin: [MetaMorphoPublicAllocator!]! @derivedFrom(field: "admin") + } @@ -2393,6 +2395,9 @@ type MetaMorphoPublicAllocator @entity(immutable: true) { allocator: MetaMorphoAllocator fee: BigInt! + accruedFee: BigInt! + claimableFee: BigInt! + claimedFee: BigInt! admin: Account diff --git a/src/public-allocator.ts b/src/public-allocator.ts index 47c1bf4..b4598c3 100644 --- a/src/public-allocator.ts +++ b/src/public-allocator.ts @@ -9,6 +9,7 @@ import { TransferFee, } from "../generated/PublicAllocator/PublicAllocator"; import { + Account, MarketFlowCapsSet, MetaMorpho, MetaMorphoAllocator, @@ -41,6 +42,9 @@ export function loadPublicAllocatorVault( pa.metaMorpho = mm.id; pa.fee = BigInt.zero(); + pa.accruedFee = BigInt.zero(); + pa.claimableFee = BigInt.zero(); + pa.claimedFee = BigInt.zero(); pa.save(); } return pa; @@ -132,6 +136,11 @@ export function handlePublicWithdrawal(event: PublicWithdrawal): void { return; } + const paVault = loadPublicAllocatorVault(event.params.vault); + paVault.accruedFee = paVault.accruedFee.plus(paVault.fee); + paVault.claimableFee = paVault.claimableFee.plus(paVault.fee); + paVault.save(); + const paMarket = loadPublicAllocatorMarket( event.params.vault, event.params.id @@ -177,12 +186,18 @@ export function handleSetAdmin(event: SetAdmin): void { if (!metaMorphoExists(event.params.vault)) { return; } + const paVault = loadPublicAllocatorVault(event.params.vault); + paVault.admin = new Account(event.params.admin).id; + paVault.save(); } export function handleSetFee(event: SetFee): void { if (!metaMorphoExists(event.params.vault)) { return; } + const paVault = loadPublicAllocatorVault(event.params.vault); + paVault.fee = event.params.fee; + paVault.save(); } export function handleSetFlowCaps(event: SetFlowCaps): void { @@ -196,4 +211,8 @@ export function handleTransferFee(event: TransferFee): void { if (!metaMorphoExists(event.params.vault)) { return; } + const pa = loadPublicAllocatorVault(event.params.vault); + pa.claimableFee = pa.claimableFee.minus(event.params.amount); + pa.claimedFee = pa.claimedFee.plus(event.params.amount); + pa.save(); } From 78b0762d0c926323dcdc50edb26922ab45642f7d Mon Sep 17 00:00:00 2001 From: Julien Date: Mon, 23 Sep 2024 11:25:21 +0200 Subject: [PATCH 06/13] feat(public-allocator): handle flow caps set --- schema.graphql | 1 - src/public-allocator.ts | 41 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/schema.graphql b/schema.graphql index 6399b0d..d8fbebc 100644 --- a/schema.graphql +++ b/schema.graphql @@ -2457,7 +2457,6 @@ type SetFlowCapsEvent implements Event @entity(immutable: true) @transaction { metaMorpho: MetaMorphoPublicAllocator! - market: MetaMorphoPublicAllocatorMarket! flowCaps: [MarketFlowCapsSet!]! @derivedFrom(field: "setFlowCapsEvent") } diff --git a/src/public-allocator.ts b/src/public-allocator.ts index b4598c3..782d178 100644 --- a/src/public-allocator.ts +++ b/src/public-allocator.ts @@ -17,6 +17,7 @@ import { MetaMorphoPublicAllocatorMarket, PublicAllocatorReallocationToEvent, PublicAllocatorWithdrawalEvent, + SetFlowCapsEvent, } from "../generated/schema"; import { loadMetaMorpho, loadMetaMorphoMarket } from "./sdk/metamorpho"; @@ -204,7 +205,45 @@ export function handleSetFlowCaps(event: SetFlowCaps): void { if (!metaMorphoExists(event.params.vault)) { return; } - const mm = loadMetaMorpho(event.params.vault); + const paVault = loadPublicAllocatorVault(event.params.vault); + + const eventId = event.transaction.hash.concat( + Bytes.fromI32(event.logIndex.toI32()) + ); + + const setFlowCapsEvent = new SetFlowCapsEvent(eventId); + + setFlowCapsEvent.hash = event.transaction.hash; + setFlowCapsEvent.nonce = event.transaction.nonce; + setFlowCapsEvent.logIndex = event.logIndex.toI32(); + setFlowCapsEvent.gasPrice = event.transaction.gasPrice; + setFlowCapsEvent.gasUsed = event.receipt ? event.receipt!.gasUsed : null; + setFlowCapsEvent.gasLimit = event.transaction.gasLimit; + setFlowCapsEvent.blockNumber = event.block.number; + setFlowCapsEvent.timestamp = event.block.timestamp; + setFlowCapsEvent.metaMorpho = paVault.id; + + setFlowCapsEvent.save(); + + for (let i = 0; i < event.params.config.length; i++) { + const config = event.params.config[i]; + + const paMarket = loadPublicAllocatorMarket(event.params.vault, config.id); + + const marketFlowCapsSet = new MarketFlowCapsSet(eventId.concat(config.id)); + marketFlowCapsSet.metaMorpho = paMarket.metaMorpho; + marketFlowCapsSet.market = paMarket.id; + marketFlowCapsSet.prevFlowCapIn = paMarket.flowCapIn; + marketFlowCapsSet.flowCapIn = config.caps.maxIn; + marketFlowCapsSet.prevFlowCapOut = paMarket.flowCapOut; + marketFlowCapsSet.flowCapOut = config.caps.maxOut; + marketFlowCapsSet.setFlowCapsEvent = setFlowCapsEvent.id; + marketFlowCapsSet.save(); + + paMarket.flowCapIn = config.caps.maxIn; + paMarket.flowCapOut = config.caps.maxOut; + paMarket.save(); + } } export function handleTransferFee(event: TransferFee): void { From b9ba4dc827206ef38ce2ea44c1157eb49966c5cb Mon Sep 17 00:00:00 2001 From: Julien Date: Mon, 23 Sep 2024 11:34:18 +0200 Subject: [PATCH 07/13] feat(public-allocator): better entity naming --- schema.graphql | 77 ++++++++++++++++++++--------------------- src/public-allocator.ts | 29 +++++++++------- 2 files changed, 55 insertions(+), 51 deletions(-) diff --git a/schema.graphql b/schema.graphql index d8fbebc..6f17133 100644 --- a/schema.graphql +++ b/schema.graphql @@ -2401,27 +2401,26 @@ type MetaMorphoPublicAllocator @entity(immutable: true) { admin: Account - markets: [MetaMorphoPublicAllocatorMarket!]! @derivedFrom(field: "metaMorpho") - setFlowCapsEvents: [SetFlowCapsEvent!]! @derivedFrom(field: "metaMorpho") - reallocationToEvents: [PublicAllocatorReallocationToEvent!]! @derivedFrom(field: "metaMorpho") - withdrawalEvents: [PublicAllocatorWithdrawalEvent!]! @derivedFrom(field: "metaMorpho") - flowCapsChanges: [MarketFlowCapsSet!]! @derivedFrom(field: "metaMorpho") + markets: [MetaMorphoPublicAllocatorMarket!]! @derivedFrom(field: "metaMorphoPublicAllocator") + setFlowCapsEvents: [SetFlowCapsEvent!]! @derivedFrom(field: "metaMorphoPublicAllocator") + reallocationToEvents: [PublicAllocatorReallocationToEvent!]! @derivedFrom(field: "metaMorphoPublicAllocator") + withdrawalEvents: [PublicAllocatorWithdrawalEvent!]! @derivedFrom(field: "metaMorphoPublicAllocator") + flowCapsChanges: [MarketFlowCapsSet!]! @derivedFrom(field: "metaMorphoPublicAllocator") } type MetaMorphoPublicAllocatorMarket @entity(immutable: true) { id: Bytes! - metaMorpho: MetaMorphoPublicAllocator! + metaMorphoPublicAllocator: MetaMorphoPublicAllocator! market: MetaMorphoMarket! flowCapIn: BigInt! flowCapOut: BigInt! - setFlowCapsEvents: [SetFlowCapsEvent!]! @derivedFrom(field: "market") - reallocationToEvents: [PublicAllocatorReallocationToEvent!]! @derivedFrom(field: "market") - withdrawalEvents: [PublicAllocatorWithdrawalEvent!]! @derivedFrom(field: "market") - flowCapsChanges: [MarketFlowCapsSet!]! @derivedFrom(field: "market") + reallocationToEvents: [PublicAllocatorReallocationToEvent!]! @derivedFrom(field: "marketPublicAllocator") + withdrawalEvents: [PublicAllocatorWithdrawalEvent!]! @derivedFrom(field: "marketPublicAllocator") + flowCapsChanges: [MarketFlowCapsSet!]! @derivedFrom(field: "marketPublicAllocator") } @@ -2454,9 +2453,7 @@ type SetFlowCapsEvent implements Event @entity(immutable: true) @transaction { " Timestamp of this event " timestamp: BigInt! - - metaMorpho: MetaMorphoPublicAllocator! - + metaMorphoPublicAllocator: MetaMorphoPublicAllocator! flowCaps: [MarketFlowCapsSet!]! @derivedFrom(field: "setFlowCapsEvent") } @@ -2490,57 +2487,59 @@ type PublicAllocatorReallocationToEvent implements Event @entity(immutable: true " Timestamp of this event " timestamp: BigInt! - metaMorpho: MetaMorphoPublicAllocator! + metaMorphoPublicAllocator: MetaMorphoPublicAllocator! - market: MetaMorphoPublicAllocatorMarket! + marketPublicAllocator: MetaMorphoPublicAllocatorMarket! suppliedAssets: BigInt! + + flowCaps: MarketFlowCapsSet! @derivedFrom(field: "publicReallocationEvent") } type PublicAllocatorWithdrawalEvent implements Event @entity(immutable: true) @transaction { - " { Transaction hash }{ Log index } " - id: Bytes! + " { Transaction hash }{ Log index } " + id: Bytes! - " Transaction hash of the transaction that emitted this event " - hash: Bytes! + " Transaction hash of the transaction that emitted this event " + hash: Bytes! - " Nonce of the transaction that emitted this event " - nonce: BigInt! + " Nonce of the transaction that emitted this event " + nonce: BigInt! - " Event log index. For transactions that don't emit event, create arbitrary index starting from 0 " - logIndex: Int! + " Event log index. For transactions that don't emit event, create arbitrary index starting from 0 " + logIndex: Int! - " Price of gas in this transaction " - gasPrice: BigInt + " Price of gas in this transaction " + gasPrice: BigInt - " Gas used in this transaction. (Optional because not every chain will support this) " - gasUsed: BigInt + " Gas used in this transaction. (Optional because not every chain will support this) " + gasUsed: BigInt - " Gas limit of this transaction. e.g. the amount of gas the sender will pay " - gasLimit: BigInt + " Gas limit of this transaction. e.g. the amount of gas the sender will pay " + gasLimit: BigInt - " Block number of this event " - blockNumber: BigInt! + " Block number of this event " + blockNumber: BigInt! - " Timestamp of this event " - timestamp: BigInt! + " Timestamp of this event " + timestamp: BigInt! - metaMorpho: MetaMorphoPublicAllocator + metaMorphoPublicAllocator: MetaMorphoPublicAllocator - market: MetaMorphoPublicAllocatorMarket + marketPublicAllocator: MetaMorphoPublicAllocatorMarket - withdrawnAssets: BigInt! + withdrawnAssets: BigInt! - flowCaps: [MarketFlowCapsSet!]! @derivedFrom(field: "publicWithdrawalEvent") + flowCaps: MarketFlowCapsSet! @derivedFrom(field: "publicWithdrawalEvent") } type MarketFlowCapsSet @entity(immutable: true) { id: Bytes! - metaMorpho: MetaMorphoPublicAllocator! + metaMorphoPublicAllocator: MetaMorphoPublicAllocator! - market: MetaMorphoPublicAllocatorMarket! + marketPublicAllocator: MetaMorphoPublicAllocatorMarket! prevFlowCapIn: BigInt! flowCapIn: BigInt! diff --git a/src/public-allocator.ts b/src/public-allocator.ts index 782d178..4a6aa52 100644 --- a/src/public-allocator.ts +++ b/src/public-allocator.ts @@ -65,7 +65,7 @@ export function loadPublicAllocatorMarket( paMarket.market = mmMarket.id; const paVault = loadPublicAllocatorVault(metaMorpho); - paMarket.metaMorpho = paVault.id; + paMarket.metaMorphoPublicAllocator = paVault.id; paMarket.flowCapIn = BigInt.zero(); paMarket.flowCapOut = BigInt.zero(); @@ -102,8 +102,9 @@ export function handlePublicReallocateTo(event: PublicReallocateTo): void { ); const marketFlowCapsSet = new MarketFlowCapsSet(eventId); - marketFlowCapsSet.metaMorpho = paMarket.metaMorpho; - marketFlowCapsSet.market = paMarket.market; + marketFlowCapsSet.metaMorphoPublicAllocator = + paMarket.metaMorphoPublicAllocator; + marketFlowCapsSet.marketPublicAllocator = paMarket.market; marketFlowCapsSet.prevFlowCapIn = paMarket.flowCapIn; marketFlowCapsSet.flowCapIn = newFlowCapIn; @@ -121,8 +122,9 @@ export function handlePublicReallocateTo(event: PublicReallocateTo): void { reallocateToEvent.gasLimit = event.transaction.gasLimit; reallocateToEvent.blockNumber = event.block.number; reallocateToEvent.timestamp = event.block.timestamp; - reallocateToEvent.metaMorpho = paMarket.metaMorpho; - reallocateToEvent.market = paMarket.id; + reallocateToEvent.metaMorphoPublicAllocator = + paMarket.metaMorphoPublicAllocator; + reallocateToEvent.marketPublicAllocator = paMarket.id; reallocateToEvent.suppliedAssets = event.params.suppliedAssets; reallocateToEvent.save(); @@ -153,8 +155,9 @@ export function handlePublicWithdrawal(event: PublicWithdrawal): void { ); const marketFlowCapsSet = new MarketFlowCapsSet(eventId); - marketFlowCapsSet.metaMorpho = paMarket.metaMorpho; - marketFlowCapsSet.market = paMarket.market; + marketFlowCapsSet.metaMorphoPublicAllocator = + paMarket.metaMorphoPublicAllocator; + marketFlowCapsSet.marketPublicAllocator = paMarket.market; marketFlowCapsSet.prevFlowCapIn = paMarket.flowCapIn; marketFlowCapsSet.flowCapIn = paMarket.flowCapIn; @@ -172,8 +175,9 @@ export function handlePublicWithdrawal(event: PublicWithdrawal): void { withdrawalEvent.gasLimit = event.transaction.gasLimit; withdrawalEvent.blockNumber = event.block.number; withdrawalEvent.timestamp = event.block.timestamp; - withdrawalEvent.metaMorpho = paMarket.metaMorpho; - withdrawalEvent.market = paMarket.id; + withdrawalEvent.metaMorphoPublicAllocator = + paMarket.metaMorphoPublicAllocator; + withdrawalEvent.marketPublicAllocator = paMarket.id; withdrawalEvent.withdrawnAssets = event.params.withdrawnAssets; withdrawalEvent.save(); @@ -221,7 +225,7 @@ export function handleSetFlowCaps(event: SetFlowCaps): void { setFlowCapsEvent.gasLimit = event.transaction.gasLimit; setFlowCapsEvent.blockNumber = event.block.number; setFlowCapsEvent.timestamp = event.block.timestamp; - setFlowCapsEvent.metaMorpho = paVault.id; + setFlowCapsEvent.metaMorphoPublicAllocator = paVault.id; setFlowCapsEvent.save(); @@ -231,8 +235,9 @@ export function handleSetFlowCaps(event: SetFlowCaps): void { const paMarket = loadPublicAllocatorMarket(event.params.vault, config.id); const marketFlowCapsSet = new MarketFlowCapsSet(eventId.concat(config.id)); - marketFlowCapsSet.metaMorpho = paMarket.metaMorpho; - marketFlowCapsSet.market = paMarket.id; + marketFlowCapsSet.metaMorphoPublicAllocator = + paMarket.metaMorphoPublicAllocator; + marketFlowCapsSet.marketPublicAllocator = paMarket.id; marketFlowCapsSet.prevFlowCapIn = paMarket.flowCapIn; marketFlowCapsSet.flowCapIn = config.caps.maxIn; marketFlowCapsSet.prevFlowCapOut = paMarket.flowCapOut; From 2b91acc23a5220b5146d61ba96796bd8c5837e2c Mon Sep 17 00:00:00 2001 From: Julien Date: Mon, 23 Sep 2024 11:41:32 +0200 Subject: [PATCH 08/13] fix(public-allocator): missing field at metamorpho creation --- schema.graphql | 6 +++--- src/meta-morpho-factory.ts | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/schema.graphql b/schema.graphql index 6f17133..5f1762f 100644 --- a/schema.graphql +++ b/schema.graphql @@ -2424,7 +2424,7 @@ type MetaMorphoPublicAllocatorMarket @entity(immutable: true) { } -type SetFlowCapsEvent implements Event @entity(immutable: true) @transaction { +type SetFlowCapsEvent @entity(immutable: true) @transaction { " { Transaction hash }{ Log index } " id: Bytes! @@ -2458,7 +2458,7 @@ type SetFlowCapsEvent implements Event @entity(immutable: true) @transaction { flowCaps: [MarketFlowCapsSet!]! @derivedFrom(field: "setFlowCapsEvent") } -type PublicAllocatorReallocationToEvent implements Event @entity(immutable: true) @transaction { +type PublicAllocatorReallocationToEvent @entity(immutable: true) @transaction { " { Transaction hash }{ Log index } " id: Bytes! @@ -2496,7 +2496,7 @@ type PublicAllocatorReallocationToEvent implements Event @entity(immutable: true flowCaps: MarketFlowCapsSet! @derivedFrom(field: "publicReallocationEvent") } -type PublicAllocatorWithdrawalEvent implements Event @entity(immutable: true) @transaction { +type PublicAllocatorWithdrawalEvent @entity(immutable: true) @transaction { " { Transaction hash }{ Log index } " id: Bytes! diff --git a/src/meta-morpho-factory.ts b/src/meta-morpho-factory.ts index abbd14b..ac322bb 100644 --- a/src/meta-morpho-factory.ts +++ b/src/meta-morpho-factory.ts @@ -48,5 +48,7 @@ export function handleCreateMetaMorpho(event: CreateMetaMorphoEvent): void { event.params.metaMorpho ).getAccount().id; + metaMorpho.hasPublicAllocator = false; + metaMorpho.save(); } From 102b6875c3770ac7141dd8bcb334ad977e5aabda Mon Sep 17 00:00:00 2001 From: Julien Date: Mon, 23 Sep 2024 12:17:35 +0200 Subject: [PATCH 09/13] fix(public-allocator): add author + fix immutable --- schema.graphql | 13 +++++++++++-- src/public-allocator.ts | 4 ++++ src/utils/publicAllocator.ts | 10 ++++++---- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/schema.graphql b/schema.graphql index 5f1762f..8058629 100644 --- a/schema.graphql +++ b/schema.graphql @@ -1369,6 +1369,9 @@ type Account @entity @regularPolling { metaMorphoTransferTo: [MetaMorphoTransfer!]! @derivedFrom(field: "to") publicAllocatorAdmin: [MetaMorphoPublicAllocator!]! @derivedFrom(field: "admin") + publicAllocatorReallocateToAuthor: [PublicAllocatorReallocationToEvent!]! @derivedFrom(field: "author") + publicAllocatorWithdrawalAuthor: [PublicAllocatorWithdrawalEvent!]! @derivedFrom(field: "author") + publicAllocatorSetFlowCapsAuthor: [SetFlowCapsEvent!]! @derivedFrom(field: "author") } @@ -2387,7 +2390,7 @@ type MetaMorphoTransfer @entity(immutable: true) { } -type MetaMorphoPublicAllocator @entity(immutable: true) { +type MetaMorphoPublicAllocator @entity { id: Bytes! metaMorpho: MetaMorpho! @@ -2409,7 +2412,7 @@ type MetaMorphoPublicAllocator @entity(immutable: true) { } -type MetaMorphoPublicAllocatorMarket @entity(immutable: true) { +type MetaMorphoPublicAllocatorMarket @entity { id: Bytes! metaMorphoPublicAllocator: MetaMorphoPublicAllocator! @@ -2453,6 +2456,8 @@ type SetFlowCapsEvent @entity(immutable: true) @transaction { " Timestamp of this event " timestamp: BigInt! + author: Account! + metaMorphoPublicAllocator: MetaMorphoPublicAllocator! flowCaps: [MarketFlowCapsSet!]! @derivedFrom(field: "setFlowCapsEvent") @@ -2487,6 +2492,8 @@ type PublicAllocatorReallocationToEvent @entity(immutable: true) @transaction { " Timestamp of this event " timestamp: BigInt! + author: Account! + metaMorphoPublicAllocator: MetaMorphoPublicAllocator! marketPublicAllocator: MetaMorphoPublicAllocatorMarket! @@ -2525,6 +2532,8 @@ type PublicAllocatorWithdrawalEvent @entity(immutable: true) @transaction { " Timestamp of this event " timestamp: BigInt! + author: Account! + metaMorphoPublicAllocator: MetaMorphoPublicAllocator marketPublicAllocator: MetaMorphoPublicAllocatorMarket diff --git a/src/public-allocator.ts b/src/public-allocator.ts index 4a6aa52..c8abe81 100644 --- a/src/public-allocator.ts +++ b/src/public-allocator.ts @@ -122,6 +122,7 @@ export function handlePublicReallocateTo(event: PublicReallocateTo): void { reallocateToEvent.gasLimit = event.transaction.gasLimit; reallocateToEvent.blockNumber = event.block.number; reallocateToEvent.timestamp = event.block.timestamp; + reallocateToEvent.author = new Account(event.params.sender).id; reallocateToEvent.metaMorphoPublicAllocator = paMarket.metaMorphoPublicAllocator; reallocateToEvent.marketPublicAllocator = paMarket.id; @@ -175,6 +176,7 @@ export function handlePublicWithdrawal(event: PublicWithdrawal): void { withdrawalEvent.gasLimit = event.transaction.gasLimit; withdrawalEvent.blockNumber = event.block.number; withdrawalEvent.timestamp = event.block.timestamp; + withdrawalEvent.author = new Account(event.params.sender).id; withdrawalEvent.metaMorphoPublicAllocator = paMarket.metaMorphoPublicAllocator; withdrawalEvent.marketPublicAllocator = paMarket.id; @@ -225,6 +227,8 @@ export function handleSetFlowCaps(event: SetFlowCaps): void { setFlowCapsEvent.gasLimit = event.transaction.gasLimit; setFlowCapsEvent.blockNumber = event.block.number; setFlowCapsEvent.timestamp = event.block.timestamp; + setFlowCapsEvent.author = new Account(event.params.sender).id; + setFlowCapsEvent.metaMorphoPublicAllocator = paVault.id; setFlowCapsEvent.save(); diff --git a/src/utils/publicAllocator.ts b/src/utils/publicAllocator.ts index 35c7d1a..96ed202 100644 --- a/src/utils/publicAllocator.ts +++ b/src/utils/publicAllocator.ts @@ -2,13 +2,15 @@ import { Address, dataSource, log } from "@graphprotocol/graph-ts"; export function getPublicAllocatorAddress(): Address { const network = dataSource.network(); - if (network === "mainnet") { + log.warning("Network id: {}", [network]); + if (network == "mainnet") { return Address.fromString("0xfd32fA2ca22c76dD6E550706Ad913FC6CE91c75D"); } - if (network === "base") { + if (network == "base") { return Address.fromString("0xA090dD1a701408Df1d4d0B85b716c87565f90467"); } - log.critical("No public allocator for network: {}", [network]); - return Address.zero(); + log.warning("No public allocator for network: {}", [network]); + return Address.fromString("0xfd32fA2ca22c76dD6E550706Ad913FC6CE91c75D"); + // TODO: throw an error instead of returning a default value } From 590e1f88301e01a220a5808e25859c579635dda8 Mon Sep 17 00:00:00 2001 From: Julien Date: Mon, 23 Sep 2024 13:37:20 +0200 Subject: [PATCH 10/13] fix(public-allocator): flowCapIn was used in publicWithdrawal --- src/public-allocator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/public-allocator.ts b/src/public-allocator.ts index c8abe81..bdf976b 100644 --- a/src/public-allocator.ts +++ b/src/public-allocator.ts @@ -149,7 +149,7 @@ export function handlePublicWithdrawal(event: PublicWithdrawal): void { event.params.vault, event.params.id ); - const newFlowCapOut = paMarket.flowCapIn.minus(event.params.withdrawnAssets); + const newFlowCapOut = paMarket.flowCapOut.minus(event.params.withdrawnAssets); const eventId = event.transaction.hash.concat( Bytes.fromI32(event.logIndex.toI32()) From dc9cc1c9ec5db57fbaf2e0e40cda634c7b27fadd Mon Sep 17 00:00:00 2001 From: Julien Date: Mon, 23 Sep 2024 13:49:37 +0200 Subject: [PATCH 11/13] docs(public-allocator): graphql docs --- schema.graphql | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/schema.graphql b/schema.graphql index 8058629..e198ff4 100644 --- a/schema.graphql +++ b/schema.graphql @@ -2391,42 +2391,70 @@ type MetaMorphoTransfer @entity(immutable: true) { } type MetaMorphoPublicAllocator @entity { + " { MetaMorpho ID } " id: Bytes! + " The MetaMorpho associated with this public allocator vault configuration " metaMorpho: MetaMorpho! + " The allocator associated with this public allocator vault configuration" allocator: MetaMorphoAllocator + " The current fee per public reallocation " fee: BigInt! + " The fee accrued by the admin " accruedFee: BigInt! + " The fee that can be claimed by the admin " claimableFee: BigInt! + " The fee claimed by the admin " claimedFee: BigInt! + " The current admin of the public allocator. Value is optional & fallbacks on the vault owner " admin: Account + " All the markets public allocator configurations. Values contained are the latest values " markets: [MetaMorphoPublicAllocatorMarket!]! @derivedFrom(field: "metaMorphoPublicAllocator") + + " All the public flow caps changes for this MetaMorpho (on all markets) " setFlowCapsEvents: [SetFlowCapsEvent!]! @derivedFrom(field: "metaMorphoPublicAllocator") + + " All the public flowIn modifications for this MetaMorpho (on all markets) " reallocationToEvents: [PublicAllocatorReallocationToEvent!]! @derivedFrom(field: "metaMorphoPublicAllocator") + + " All the public flowOut modifications for this MetaMorpho (on all markets) " withdrawalEvents: [PublicAllocatorWithdrawalEvent!]! @derivedFrom(field: "metaMorphoPublicAllocator") + + " All the flow caps changes for this MetaMorpho (on all markets) " flowCapsChanges: [MarketFlowCapsSet!]! @derivedFrom(field: "metaMorphoPublicAllocator") } type MetaMorphoPublicAllocatorMarket @entity { + " { MetaMorpho ID }-{ Market ID } " id: Bytes! + " The MetaMorpho public allocator configuration. Values contained are the latest values " metaMorphoPublicAllocator: MetaMorphoPublicAllocator! + " The MetaMorpho market associated with the public allocator " market: MetaMorphoMarket! + " The current flow cap in for this market for the given MetaMorpho " flowCapIn: BigInt! + " The current flow cap out for this market for the given MetaMorpho " flowCapOut: BigInt! + " All the public flowIn modifications for this market for the given MetaMorpho " reallocationToEvents: [PublicAllocatorReallocationToEvent!]! @derivedFrom(field: "marketPublicAllocator") + + " All the public flowOut modifications for this market for the given MetaMorpho " withdrawalEvents: [PublicAllocatorWithdrawalEvent!]! @derivedFrom(field: "marketPublicAllocator") + + " All the flow caps changes for this market for the given MetaMorpho " flowCapsChanges: [MarketFlowCapsSet!]! @derivedFrom(field: "marketPublicAllocator") } +" The event emitted when the flow caps are set by the public allocator admin " type SetFlowCapsEvent @entity(immutable: true) @transaction { " { Transaction hash }{ Log index } " @@ -2456,13 +2484,17 @@ type SetFlowCapsEvent @entity(immutable: true) @transaction { " Timestamp of this event " timestamp: BigInt! + " Author of the Public allocator call " author: Account! + " The metaMorpho public allocator configuration. Values contained are the latest values " metaMorphoPublicAllocator: MetaMorphoPublicAllocator! + " The different flow caps set by this event. " flowCaps: [MarketFlowCapsSet!]! @derivedFrom(field: "setFlowCapsEvent") } +" The event emitted when the public allocator reallocates assets to a market. This function is publicly accessible " type PublicAllocatorReallocationToEvent @entity(immutable: true) @transaction { " { Transaction hash }{ Log index } " @@ -2492,17 +2524,23 @@ type PublicAllocatorReallocationToEvent @entity(immutable: true) @transaction { " Timestamp of this event " timestamp: BigInt! + " Author of the Public allocator call " author: Account! + " The metaMorpho public allocator configuration. Values contained are the latest values " metaMorphoPublicAllocator: MetaMorphoPublicAllocator! + " The latest market public allocator configuration. Values contained are the latest values " marketPublicAllocator: MetaMorphoPublicAllocatorMarket! + " The amount of assets supplied " suppliedAssets: BigInt! + " The flow caps modification set by this event " flowCaps: MarketFlowCapsSet! @derivedFrom(field: "publicReallocationEvent") } +" The event emitted when the public allocator withdraws assets from a market. This function is publicly accessible " type PublicAllocatorWithdrawalEvent @entity(immutable: true) @transaction { " { Transaction hash }{ Log index } " @@ -2532,33 +2570,51 @@ type PublicAllocatorWithdrawalEvent @entity(immutable: true) @transaction { " Timestamp of this event " timestamp: BigInt! + " Author of the Public allocator call " author: Account! + " The metaMorpho public allocator configuration. Values contained are the latest values " metaMorphoPublicAllocator: MetaMorphoPublicAllocator + " The latest market public allocator configuration. Values contained are the latest values " marketPublicAllocator: MetaMorphoPublicAllocatorMarket + " The amount of assets withdrawn " withdrawnAssets: BigInt! + " The flow caps modification set by this event " flowCaps: MarketFlowCapsSet! @derivedFrom(field: "publicWithdrawalEvent") } +" Register of any change of the flow caps, either if it comes from a public call or an admin call (FlowCapSetEvent) " type MarketFlowCapsSet @entity(immutable: true) { + " { Transaction hash }{ Log index }{ markedId if applicable } " id: Bytes! + " The metaMorpho public allocator configuration. Values contained are the latest values " metaMorphoPublicAllocator: MetaMorphoPublicAllocator! + " The latest market public allocator configuration. Values contained are the latest values " marketPublicAllocator: MetaMorphoPublicAllocatorMarket! + " The previous flow cap in value " prevFlowCapIn: BigInt! + " The new flow cap in value " flowCapIn: BigInt! + " The previous flow cap out value " prevFlowCapOut: BigInt! + " The new flow cap out value " flowCapOut: BigInt! + " The set flow caps event that has set this flow caps. null if this is not set by a set flow caps event " setFlowCapsEvent: SetFlowCapsEvent + + " The public reallocation event that has set this flow caps. null if this is not set by a reallocation event " publicReallocationEvent: PublicAllocatorReallocationToEvent + + " The public withdrawal event that has set this flow caps. null if this is not set by a withdrawal event " publicWithdrawalEvent: PublicAllocatorWithdrawalEvent } From 85df728495769eeb74d59ebcce8be0f27b64a6f4 Mon Sep 17 00:00:00 2001 From: Julien Date: Mon, 23 Sep 2024 13:56:10 +0200 Subject: [PATCH 12/13] fix(public-allocator): network without public allocator fallbacks on zeroAddress --- src/utils/publicAllocator.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/utils/publicAllocator.ts b/src/utils/publicAllocator.ts index 96ed202..814bc4a 100644 --- a/src/utils/publicAllocator.ts +++ b/src/utils/publicAllocator.ts @@ -2,7 +2,6 @@ import { Address, dataSource, log } from "@graphprotocol/graph-ts"; export function getPublicAllocatorAddress(): Address { const network = dataSource.network(); - log.warning("Network id: {}", [network]); if (network == "mainnet") { return Address.fromString("0xfd32fA2ca22c76dD6E550706Ad913FC6CE91c75D"); } @@ -10,7 +9,6 @@ export function getPublicAllocatorAddress(): Address { return Address.fromString("0xA090dD1a701408Df1d4d0B85b716c87565f90467"); } - log.warning("No public allocator for network: {}", [network]); - return Address.fromString("0xfd32fA2ca22c76dD6E550706Ad913FC6CE91c75D"); - // TODO: throw an error instead of returning a default value + log.warning("Unsupported Network id: {}", [network]); + return Address.zero(); } From 7b772c6eede4fff395fe448cc8743ea30f6b13ea Mon Sep 17 00:00:00 2001 From: julien Date: Tue, 1 Oct 2024 14:45:22 +0200 Subject: [PATCH 13/13] fix(public-allocator): flow caps are sometime negative --- src/public-allocator.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/public-allocator.ts b/src/public-allocator.ts index bdf976b..1ac8414 100644 --- a/src/public-allocator.ts +++ b/src/public-allocator.ts @@ -96,6 +96,7 @@ export function handlePublicReallocateTo(event: PublicReallocateTo): void { event.params.supplyMarketId ); const newFlowCapIn = paMarket.flowCapIn.minus(event.params.suppliedAssets); + const newFlowCapOut = paMarket.flowCapOut.plus(event.params.suppliedAssets); const eventId = event.transaction.hash.concat( Bytes.fromI32(event.logIndex.toI32()) @@ -110,7 +111,7 @@ export function handlePublicReallocateTo(event: PublicReallocateTo): void { marketFlowCapsSet.flowCapIn = newFlowCapIn; marketFlowCapsSet.prevFlowCapOut = paMarket.flowCapOut; - marketFlowCapsSet.flowCapOut = paMarket.flowCapOut; + marketFlowCapsSet.flowCapOut = newFlowCapOut; const reallocateToEvent = new PublicAllocatorReallocationToEvent(eventId); @@ -132,6 +133,7 @@ export function handlePublicReallocateTo(event: PublicReallocateTo): void { marketFlowCapsSet.publicReallocationEvent = reallocateToEvent.id; marketFlowCapsSet.save(); paMarket.flowCapIn = newFlowCapIn; + paMarket.flowCapOut = newFlowCapOut; paMarket.save(); } @@ -150,6 +152,7 @@ export function handlePublicWithdrawal(event: PublicWithdrawal): void { event.params.id ); const newFlowCapOut = paMarket.flowCapOut.minus(event.params.withdrawnAssets); + const newFlowCapIn = paMarket.flowCapIn.plus(event.params.withdrawnAssets); const eventId = event.transaction.hash.concat( Bytes.fromI32(event.logIndex.toI32()) @@ -161,7 +164,7 @@ export function handlePublicWithdrawal(event: PublicWithdrawal): void { marketFlowCapsSet.marketPublicAllocator = paMarket.market; marketFlowCapsSet.prevFlowCapIn = paMarket.flowCapIn; - marketFlowCapsSet.flowCapIn = paMarket.flowCapIn; + marketFlowCapsSet.flowCapIn = newFlowCapIn; marketFlowCapsSet.prevFlowCapOut = paMarket.flowCapOut; marketFlowCapsSet.flowCapOut = newFlowCapOut; @@ -185,6 +188,7 @@ export function handlePublicWithdrawal(event: PublicWithdrawal): void { marketFlowCapsSet.publicWithdrawalEvent = withdrawalEvent.id; marketFlowCapsSet.save(); + paMarket.flowCapIn = newFlowCapIn; paMarket.flowCapOut = newFlowCapOut; paMarket.save(); }