Skip to content

Commit

Permalink
Add support for initializable contract deployed with deployer
Browse files Browse the repository at this point in the history
  • Loading branch information
prevostc committed Sep 2, 2024
1 parent b68aedc commit dc02f5b
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 13 deletions.
8 changes: 8 additions & 0 deletions abis/beefy/Initializable.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
{
"anonymous": false,
"inputs": [{ "indexed": false, "internalType": "uint8", "name": "version", "type": "uint8" }],
"name": "Initialized",
"type": "event"
}
]
2 changes: 0 additions & 2 deletions src/common/interaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ export function handleProductTransfer(event: TransferEvent): void {
function updateAccountBalance(tokenAddress: Bytes, accountAddress: Bytes, amountDiff: BigInt): BalanceDiff {
const account = createAccount(accountAddress)
const token = getToken(tokenAddress)
token.save()

const balance = getTokenBalance(token, account)
const before = balance.amount
const after = balance.amount.plus(amountDiff)
Expand Down
35 changes: 35 additions & 0 deletions src/common/mapping/contract-deployer-initializable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { BeefyERC20Product as BeefyERC20ProductTemplate } from "../../../generated/templates"
import { Initialized as InitializedEvent } from "../../../generated/ContractDeployer/Initializable"
import { IERC20 as IERC20Contract } from "../../../generated/templates/BeefyERC20Product/IERC20"
import { Address, log } from "@graphprotocol/graph-ts"
import { fetchAndSaveTokenData } from "../utils/token"

export function handleContractDeployedInitializableInitialized(event: InitializedEvent): void {
const tokenAddress = event.address

// detect if we are creating an erc20 token
const tokenContract = IERC20Contract.bind(Address.fromBytes(tokenAddress))

const tokenDecimalsRes = tokenContract.try_decimals()
if (tokenDecimalsRes.reverted) {
log.info("Contract {} is not an ERC20 token, decimals() reverted", [tokenAddress.toHexString()])
return
}

const tokenNameRes = tokenContract.try_name()
if (tokenNameRes.reverted) {
log.info("Contract {} is not an ERC20 token, name() reverted", [tokenAddress.toHexString()])
return
}

const tokenSymbolRes = tokenContract.try_symbol()
if (tokenSymbolRes.reverted) {
log.info("Contract {} is not an ERC20 token, symbol() reverted", [tokenAddress.toHexString()])
return
}

log.debug("Creating BeefyERC20Product template for {} from contract-deployer", [tokenAddress.toHexString()])

fetchAndSaveTokenData(tokenAddress)
BeefyERC20ProductTemplate.create(tokenAddress)
}
20 changes: 13 additions & 7 deletions src/common/mapping/contract-deployer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { BeefyERC20Product as BeefyERC20ProductTemplate } from "../../../generated/templates"
import {
BeefyERC20Product as BeefyERC20ProductTemplate,
ContractDeployerInitializable as ContractDeployerInitializableTemplate,
} from "../../../generated/templates"
import { ContractDeployed as ContractDeployedEvent } from "../../../generated/ContractDeployer/ContractDeployer"
import { IERC20 as IERC20Contract } from "../../../generated/templates/BeefyERC20Product/IERC20"
import { fetchAndSaveTokenData } from "../utils/token"
Expand All @@ -9,27 +12,30 @@ export function handleContractDeployedWithDeployer(event: ContractDeployedEvent)

// detect if we are creating an erc20 token
const tokenContract = IERC20Contract.bind(Address.fromBytes(address))

const tokenDecimalsRes = tokenContract.try_decimals()
if (tokenDecimalsRes.reverted) {
log.info("Contract {} is not an ERC20 token, decimals() reverted", [address.toHexString()])
return
}

const tokenNameRes = tokenContract.try_name()
if (tokenNameRes.reverted) {
log.info("Contract {} is not an ERC20 token, name() reverted", [address.toHexString()])
return
}

const tokenSymbolRes = tokenContract.try_symbol()
if (tokenSymbolRes.reverted) {
log.info("Contract {} is not an ERC20 token, symbol() reverted", [address.toHexString()])
return
}

log.debug("Creating BeefyERC20Product template for {} from contract-deployer", [address.toHexString()])
// if any of the calls return null, this is most likely an initializable contract
if (tokenDecimalsRes.value == null || tokenNameRes.value == null || tokenSymbolRes.value == null) {
log.info("Contract {} is probably innitializable, one of the metadata calls returned null", [address.toHexString()])

fetchAndSaveTokenData(address)
BeefyERC20ProductTemplate.create(address)
ContractDeployerInitializableTemplate.create(address)
} else {
log.debug("Creating BeefyERC20Product template for {} from contract-deployer", [address.toHexString()])
fetchAndSaveTokenData(address)
BeefyERC20ProductTemplate.create(address)
}
}
7 changes: 3 additions & 4 deletions src/common/utils/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@ export function fetchAndSaveTokenData(tokenAddress: Bytes): Token {

// if any of these calls revert, we will just use the default values to avoid a subgraph crash
const tokenDecimalsRes = tokenContract.try_decimals()
const tokenDecimals = tokenDecimalsRes.reverted ? 18 : tokenDecimalsRes.value

const tokenNameRes = tokenContract.try_name()
const tokenName = tokenNameRes.reverted ? "Unknown" : tokenNameRes.value

const tokenSymbolRes = tokenContract.try_symbol()

const tokenDecimals = tokenDecimalsRes.reverted ? 18 : tokenDecimalsRes.value
const tokenName = tokenNameRes.reverted ? "Unknown" : tokenNameRes.value
const tokenSymbol = tokenSymbolRes.reverted ? "UNKNOWN" : tokenSymbolRes.value

const token = getToken(tokenAddress)
Expand Down
20 changes: 20 additions & 0 deletions subgraph.template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@ dataSources:
file: ./abis/beefy/ContractDeployer.json
- name: IERC20
file: ./abis/IERC20/IERC20.json
- name: Initializable
file: ./abis/beefy/Initializable.json
eventHandlers:
- event: ContractDeployed(indexed bytes32,address)
handler: handleContractDeployedWithDeployer
Expand Down Expand Up @@ -268,6 +270,24 @@ templates:
handler: handleClassicVaultInitialized
{{/beefyClassicVaultFactoryAddress}}

{{#beefyContractDeployerAddress}}
- name: ContractDeployerInitializable
kind: ethereum/contract
network: {{network}}
source:
abi: Initializable
mapping:
kind: ethereum/events
apiVersion: 0.0.7 # 0xgraph's version
language: wasm/assemblyscript
file: ./src/common/mapping/contract-deployer-initializable.ts
entities: *contractDeployerEntities
abis: *contractDeployerAbis
eventHandlers:
- event: Initialized(uint8)
handler: handleContractDeployedInitializableInitialized
{{/beefyContractDeployerAddress}}

- name: BeefyERC20Product
kind: ethereum/contract
network: {{network}}
Expand Down

0 comments on commit dc02f5b

Please sign in to comment.