diff --git a/package.json b/package.json index bb532735..da1c101a 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "@venusprotocol/governance-contracts": "2.10.0", "@venusprotocol/isolated-pools": "4.2.0-dev.9", "@venusprotocol/oracle": "2.9.0", - "@venusprotocol/protocol-reserve": "3.1.0", + "@venusprotocol/protocol-reserve": "3.4.0-dev.3", "@venusprotocol/solidity-utilities": "^2.0.3", "@venusprotocol/venus-protocol": "9.6.0", "assemblyscript": "0.19.23", @@ -90,7 +90,7 @@ "resolutions": { "@venusprotocol/governance-contracts": "2.10.0", "@venusprotocol/venus-protocol": "9.6.0", - "@venusprotocol/protocol-reserve": "3.1.0", + "@venusprotocol/protocol-reserve": "3.4.0-dev.3", "prettier": "^3.0.3" }, "husky": { diff --git a/subgraphs/protocol-reserve/config/index.ts b/subgraphs/protocol-reserve/config/index.ts index 684df1f3..3db8b8bb 100644 --- a/subgraphs/protocol-reserve/config/index.ts +++ b/subgraphs/protocol-reserve/config/index.ts @@ -34,6 +34,8 @@ const main = () => { usdtPrimeConverterStartBlock: '0', xvsVaultConverterAddress: '0xa779C1D17bC5230c07afdC51376CAC1cb3Dd5314', xvsVaultConverterStartBlock: '0', + wBnbBurnConverterAddress: '0xa079C1D17bC5230c07afdC51376CAC1cb3Dd5314', + wBnbBurnConverterStartBlock: '0', riskFundAddress: '0x8d81a3dcd17030cd5f23ac7370e4efb10d2b3ca4', protocolShareReserveAddress: '0x70e0bA845a1A0F2DA3359C97E0285013525FFC49', protocolShareReserveStartBlock: '0', @@ -55,6 +57,8 @@ const main = () => { usdtPrimeConverterStartBlock: '36750639', xvsVaultConverterAddress: chapelDeployments.addresses.XVSVaultConverter, xvsVaultConverterStartBlock: '36750678', + wBnbBurnConverterAddress: chapelDeployments.addresses.WBNBBurnConverter, + wBnbBurnConverterStartBlock: '54160930', riskFundAddress: chapelDeployments.addresses.RiskFundV2, StartBlock: '36750498', protocolShareReserveAddress: chapelDeployments.addresses.ProtocolShareReserve, @@ -77,6 +81,8 @@ const main = () => { usdtPrimeConverterStartBlock: '35140081', xvsVaultConverterAddress: bscMainnetDeployments.addresses.XVSVaultConverter, xvsVaultConverterStartBlock: '35140090', + wBnbBurnConverterAddress: bscMainnetDeployments.addresses.WBNBBurnConverter, + wBnbBurnConverterStartBlock: '51144405', riskFundAddress: bscMainnetDeployments.addresses.RiskFundV2, protocolShareReserveAddress: bscMainnetDeployments.addresses.ProtocolShareReserve, protocolShareReserveStartBlock: '32659440', diff --git a/subgraphs/protocol-reserve/schema.graphql b/subgraphs/protocol-reserve/schema.graphql index f6824d95..1db37502 100644 --- a/subgraphs/protocol-reserve/schema.graphql +++ b/subgraphs/protocol-reserve/schema.graphql @@ -38,6 +38,7 @@ type TokenConverter @entity { destinationAddress: Bytes! baseAsset: Token! configs: [TokenConverterConfig!]! @derivedFrom(field: "tokenConverter") + destinationAmounts: [DestinationAmount!]! @derivedFrom(field: "tokenConverter") paused: Boolean! priceOracleAddress: Bytes! } @@ -54,3 +55,14 @@ type TokenConverterConfig @entity { access: ConversionAccessibility! tokenOutBalance: BigInt! } + +""" +Destination Amounts +""" +type DestinationAmount @entity { + id: Bytes! + address: Bytes! + tokenConverter: TokenConverter! + token: Token! + amount: BigInt! +} diff --git a/subgraphs/protocol-reserve/src/constants/addresses.ts b/subgraphs/protocol-reserve/src/constants/addresses.ts index 82b2daf7..b57942de 100644 --- a/subgraphs/protocol-reserve/src/constants/addresses.ts +++ b/subgraphs/protocol-reserve/src/constants/addresses.ts @@ -11,6 +11,7 @@ import { wbtcPrimeConverterAddress as wbtcPrimeConverterAddressString, wethPrimeConverterAddress as wethPrimeConverterAddressString, xvsVaultConverterAddress as xvsVaultConverterAddressString, + wBnbBurnConverterAddress as wBnbBurnConverterAddressString, } from './config'; export const nullAddress = Address.fromString('0x0000000000000000000000000000000000000000'); @@ -31,5 +32,6 @@ export const usdtPrimeConverterAddress = addressFromCleanString(usdtPrimeConvert export const xvsVaultConverterAddress = addressFromCleanString(xvsVaultConverterAddressString); export const wbtcPrimeConverterAddress = addressFromCleanString(wbtcPrimeConverterAddressString); export const wethPrimeConverterAddress = addressFromCleanString(wethPrimeConverterAddressString); +export const wBnbBurnConverterAddress = addressFromCleanString(wBnbBurnConverterAddressString); export const riskFundAddress = addressFromCleanString(riskFundAddressString); diff --git a/subgraphs/protocol-reserve/src/constants/config-template b/subgraphs/protocol-reserve/src/constants/config-template index ffc94c83..c27ddc58 100644 --- a/subgraphs/protocol-reserve/src/constants/config-template +++ b/subgraphs/protocol-reserve/src/constants/config-template @@ -8,6 +8,7 @@ export const riskFundConverterAddress = '{{riskFundConverterAddress}}'; export const usdcPrimeConverterAddress = '{{usdcPrimeConverterAddress}}'; export const usdtPrimeConverterAddress = '{{usdtPrimeConverterAddress}}'; export const xvsVaultConverterAddress = '{{xvsVaultConverterAddress}}'; +export const wBnbBurnConverterAddress = '{{wBnbBurnConverterAddress}}'; export const wbtcPrimeConverterAddress = '{{wbtcPrimeConverterAddress}}'; export const wethPrimeConverterAddress = '{{wethPrimeConverterAddress}}'; diff --git a/subgraphs/protocol-reserve/src/mappings/tokenConverter.ts b/subgraphs/protocol-reserve/src/mappings/tokenConverter.ts index 3294a18b..72066143 100644 --- a/subgraphs/protocol-reserve/src/mappings/tokenConverter.ts +++ b/subgraphs/protocol-reserve/src/mappings/tokenConverter.ts @@ -1,7 +1,9 @@ -import { ethereum } from '@graphprotocol/graph-ts'; +import { Address, ethereum } from '@graphprotocol/graph-ts'; import { + AssetTransferredToDestination, BaseAssetUpdated, + ConvertedExactTokens, ConversionConfigUpdated, ConversionPaused, ConversionResumed, @@ -18,9 +20,10 @@ import { wbtcPrimeConverterAddress, wethPrimeConverterAddress, xvsVaultConverterAddress, + wBnbBurnConverterAddress, } from '../constants/addresses'; import { getTokenConverter } from '../operations/get'; -import { getOrCreateTokenConverter } from '../operations/getOrCreate'; +import { getOrCreateDestinationAmount, getOrCreateTokenConverter } from '../operations/getOrCreate'; import { updateOrCreateTokenConverterConfig } from '../operations/updateOrCreate'; import { getConverterNetworkId } from '../utilities/ids'; @@ -59,6 +62,11 @@ export function handleInitializationWethPrimeConverter(block: ethereum.Block): v getOrCreateTokenConverter(wethPrimeConverterAddress); } +// eslint-disable-next-line @typescript-eslint/no-unused-vars +export function handleInitializationWBnbBurnConverter(block: ethereum.Block): void { + getOrCreateTokenConverter(wBnbBurnConverterAddress); +} + export function handleConversionConfigUpdated(event: ConversionConfigUpdated): void { getOrCreateTokenConverter(event.address); updateOrCreateTokenConverterConfig(event.address, event.params); @@ -99,3 +107,48 @@ export function handlePriceOracleUpdated(event: PriceOracleUpdated): void { tokenConverter.priceOracleAddress = event.params.priceOracle; tokenConverter.save(); } + +export function handleConvertedExactTokens(event: ConvertedExactTokens): void { + const tokenConverter = getTokenConverter(event.address)!; + + // handle private conversions (conversions between converters) + const senderConverter = getTokenConverter(event.params.sender); + if (!!senderConverter && senderConverter.address !== riskFundConverterAddress) { + const senderDestinationAmount = getOrCreateDestinationAmount( + Address.fromBytes(senderConverter.address), + Address.fromBytes(senderConverter.destinationAddress), + event.params.tokenAddressOut, + ); + senderDestinationAmount.amount = senderDestinationAmount.amount.plus(event.params.amountOut); + senderDestinationAmount.save(); + } + + const destinationAmountEntity = getOrCreateDestinationAmount( + event.address, + Address.fromBytes(tokenConverter.destinationAddress), + event.params.tokenAddressIn, + ); + destinationAmountEntity.amount = destinationAmountEntity.amount.plus(event.params.amountIn); + destinationAmountEntity.save(); +} + +export function handleConversionEvent(event: ConvertedExactTokens): void { + const tokenConverter = getTokenConverter(event.address)!; + const destinationAmountEntity = getOrCreateDestinationAmount( + event.address, + Address.fromBytes(tokenConverter.destinationAddress), + event.params.tokenAddressIn, + ); + destinationAmountEntity.amount = destinationAmountEntity.amount.plus(event.params.amountIn); + destinationAmountEntity.save(); +} + +export function handleAssetTransferredToDestination(event: AssetTransferredToDestination): void { + const destinationAmountEntity = getOrCreateDestinationAmount( + event.address, + event.params.receiver, + event.params.asset, + ); + destinationAmountEntity.amount = destinationAmountEntity.amount.plus(event.params.amount); + destinationAmountEntity.save(); +} diff --git a/subgraphs/protocol-reserve/src/operations/getOrCreate.ts b/subgraphs/protocol-reserve/src/operations/getOrCreate.ts index 9a1a4dd0..06d899c9 100644 --- a/subgraphs/protocol-reserve/src/operations/getOrCreate.ts +++ b/subgraphs/protocol-reserve/src/operations/getOrCreate.ts @@ -1,8 +1,13 @@ -import { Address } from '@graphprotocol/graph-ts'; +import { Address, BigInt } from '@graphprotocol/graph-ts'; import { ERC20 } from '../../generated/RiskFundConverter/ERC20'; -import { Token, TokenConverter, TokenConverterConfig } from '../../generated/schema'; -import { getAssetId } from '../utilities/ids'; +import { + DestinationAmount, + Token, + TokenConverter, + TokenConverterConfig, +} from '../../generated/schema'; +import { getAssetId, getDestinationAmountId, getTokenConverterId } from '../utilities/ids'; import { createTokenConverter, createTokenConverterConfig } from './create'; import { getTokenConverter, getTokenConverterConfig } from './get'; @@ -44,7 +49,7 @@ export function getOrCreateTokenConverterConfig( } /** - * Creates and Token object with symbol and address + * Creates a Token object with symbol and address * * @param asset Address of the token * @returns Token @@ -62,3 +67,28 @@ export function getOrCreateToken(asset: Address): Token { } return tokenEntity; } + +/** + * Creates a DestinationAmount object + * + * @param asset Address of the token + * @returns Token + */ +export function getOrCreateDestinationAmount( + tokenConverterAddress: Address, + destinationAddress: Address, + tokenAddress: Address, +): DestinationAmount { + const entityId = getDestinationAmountId(tokenConverterAddress, destinationAddress, tokenAddress); + let destinationAmountEntity = DestinationAmount.load(entityId); + + if (!destinationAmountEntity) { + destinationAmountEntity = new DestinationAmount(entityId); + destinationAmountEntity.tokenConverter = getTokenConverterId(tokenConverterAddress); + destinationAmountEntity.token = getOrCreateToken(tokenAddress).id; + destinationAmountEntity.amount = BigInt.zero(); + destinationAmountEntity.address = destinationAddress; + } + + return destinationAmountEntity; +} diff --git a/subgraphs/protocol-reserve/src/utilities/ids.ts b/subgraphs/protocol-reserve/src/utilities/ids.ts index 7a30f235..84c0f4c7 100644 --- a/subgraphs/protocol-reserve/src/utilities/ids.ts +++ b/subgraphs/protocol-reserve/src/utilities/ids.ts @@ -11,3 +11,9 @@ export const getTokenConverterConfigId = ( ): Bytes => tokenConverterAddress.concat(tokenAddressIn).concat(tokenAddressOut); export const getAssetId = (asset: Address): Bytes => asset; + +export const getDestinationAmountId = ( + tokenConverterAddress: Address, + destinationAddress: Address, + tokenAddress: Address, +): Bytes => tokenConverterAddress.concat(destinationAddress).concat(tokenAddress); diff --git a/subgraphs/protocol-reserve/template.yaml b/subgraphs/protocol-reserve/template.yaml index 5720d7a6..36f8b9ca 100644 --- a/subgraphs/protocol-reserve/template.yaml +++ b/subgraphs/protocol-reserve/template.yaml @@ -68,6 +68,16 @@ dataSources: handler: handleDestinationAddressUpdated - event: PriceOracleUpdated(indexed address,indexed address) handler: handlePriceOracleUpdated + - event: ConvertedExactTokens(indexed address,indexed address,address,indexed address,uint256,uint256) + handler: handleConvertedExactTokens + - event: ConvertedForExactTokens(indexed address,indexed address,address,indexed address,uint256,uint256) + handler: handleConversionEvent + - event: ConvertedExactTokensSupportingFeeOnTransferTokens(indexed address,indexed address,address,indexed address,uint256,uint256) + handler: handleConversionEvent + - event: ConvertedForExactTokensSupportingFeeOnTransferTokens(indexed address,indexed address,address,indexed address,uint256,uint256) + handler: handleConversionEvent + - event: AssetTransferredToDestination(indexed address,indexed address,indexed address,uint256) + handler: handleAssetTransferredToDestination blockHandlers: - handler: handleInitializationBtcbPrimeConverter filter: @@ -108,6 +118,16 @@ dataSources: handler: handleDestinationAddressUpdated - event: PriceOracleUpdated(indexed address,indexed address) handler: handlePriceOracleUpdated + - event: ConvertedExactTokens(indexed address,indexed address,address,indexed address,uint256,uint256) + handler: handleConvertedExactTokens + - event: ConvertedForExactTokens(indexed address,indexed address,address,indexed address,uint256,uint256) + handler: handleConversionEvent + - event: ConvertedExactTokensSupportingFeeOnTransferTokens(indexed address,indexed address,address,indexed address,uint256,uint256) + handler: handleConversionEvent + - event: ConvertedForExactTokensSupportingFeeOnTransferTokens(indexed address,indexed address,address,indexed address,uint256,uint256) + handler: handleConversionEvent + - event: AssetTransferredToDestination(indexed address,indexed address,indexed address,uint256) + handler: handleAssetTransferredToDestination blockHandlers: - handler: handleInitializationEthPrimeConverter filter: @@ -146,6 +166,16 @@ dataSources: handler: handleDestinationAddressUpdated - event: PriceOracleUpdated(indexed address,indexed address) handler: handlePriceOracleUpdated + - event: ConvertedExactTokens(indexed address,indexed address,address,indexed address,uint256,uint256) + handler: handleConvertedExactTokens + - event: ConvertedForExactTokens(indexed address,indexed address,address,indexed address,uint256,uint256) + handler: handleConversionEvent + - event: ConvertedExactTokensSupportingFeeOnTransferTokens(indexed address,indexed address,address,indexed address,uint256,uint256) + handler: handleConversionEvent + - event: ConvertedForExactTokensSupportingFeeOnTransferTokens(indexed address,indexed address,address,indexed address,uint256,uint256) + handler: handleConversionEvent + - event: AssetTransferredToDestination(indexed address,indexed address,indexed address,uint256) + handler: handleAssetTransferredToDestination blockHandlers: - handler: handleInitializationRiskFundConverter filter: @@ -186,6 +216,16 @@ dataSources: handler: handleDestinationAddressUpdated - event: PriceOracleUpdated(indexed address,indexed address) handler: handlePriceOracleUpdated + - event: ConvertedExactTokens(indexed address,indexed address,address,indexed address,uint256,uint256) + handler: handleConvertedExactTokens + - event: ConvertedForExactTokens(indexed address,indexed address,address,indexed address,uint256,uint256) + handler: handleConversionEvent + - event: ConvertedExactTokensSupportingFeeOnTransferTokens(indexed address,indexed address,address,indexed address,uint256,uint256) + handler: handleConversionEvent + - event: ConvertedForExactTokensSupportingFeeOnTransferTokens(indexed address,indexed address,address,indexed address,uint256,uint256) + handler: handleConversionEvent + - event: AssetTransferredToDestination(indexed address,indexed address,indexed address,uint256) + handler: handleAssetTransferredToDestination blockHandlers: - handler: handleInitializationUsdcPrimeConverter filter: @@ -226,6 +266,16 @@ dataSources: handler: handleDestinationAddressUpdated - event: PriceOracleUpdated(indexed address,indexed address) handler: handlePriceOracleUpdated + - event: ConvertedExactTokens(indexed address,indexed address,address,indexed address,uint256,uint256) + handler: handleConvertedExactTokens + - event: ConvertedForExactTokens(indexed address,indexed address,address,indexed address,uint256,uint256) + handler: handleConversionEvent + - event: ConvertedExactTokensSupportingFeeOnTransferTokens(indexed address,indexed address,address,indexed address,uint256,uint256) + handler: handleConversionEvent + - event: ConvertedForExactTokensSupportingFeeOnTransferTokens(indexed address,indexed address,address,indexed address,uint256,uint256) + handler: handleConversionEvent + - event: AssetTransferredToDestination(indexed address,indexed address,indexed address,uint256) + handler: handleAssetTransferredToDestination blockHandlers: - handler: handleInitializationUsdtPrimeConverter filter: @@ -266,10 +316,70 @@ dataSources: handler: handleBaseAssetUpdated - event: PriceOracleUpdated(indexed address,indexed address) handler: handlePriceOracleUpdated + - event: ConvertedExactTokens(indexed address,indexed address,address,indexed address,uint256,uint256) + handler: handleConvertedExactTokens + - event: ConvertedForExactTokens(indexed address,indexed address,address,indexed address,uint256,uint256) + handler: handleConversionEvent + - event: ConvertedExactTokensSupportingFeeOnTransferTokens(indexed address,indexed address,address,indexed address,uint256,uint256) + handler: handleConversionEvent + - event: ConvertedForExactTokensSupportingFeeOnTransferTokens(indexed address,indexed address,address,indexed address,uint256,uint256) + handler: handleConversionEvent + - event: AssetTransferredToDestination(indexed address,indexed address,indexed address,uint256) + handler: handleAssetTransferredToDestination blockHandlers: - handler: handleInitializationXvsVaultConverter filter: kind: once + - name: WBnbBurnConverter + kind: ethereum/contract + network: {{ network }} + source: + abi: TokenConverter + address: "{{ wBnbBurnConverterAddress }}" + startBlock: {{ wBnbBurnConverterStartBlock }} + mapping: + kind: ethereum/events + apiVersion: 0.0.9 + language: wasm/assemblyscript + file: ./src/mappings/tokenConverter.ts + entities: + - TokenConverter + abis: + - name: TokenConverter + file: ../../node_modules/@venusprotocol/protocol-reserve/artifacts/contracts/TokenConverter/SingleTokenConverter.sol/SingleTokenConverter.json + - name: RiskFund + file: ../../node_modules/@venusprotocol/protocol-reserve/artifacts/contracts/Interfaces/IRiskFund.sol/IRiskFundGetters.json + - name: ERC20 + file: ../../node_modules/@venusprotocol/protocol-reserve/artifacts/@openzeppelin/contracts/token/ERC20/ERC20.sol/ERC20.json + eventHandlers: + - event: ConversionConfigUpdated(indexed address,indexed address,uint256,uint256,uint8,uint8) + handler: handleConversionConfigUpdated + - event: ConversionPaused(indexed address) + handler: handleConversionPaused + - event: ConversionResumed(indexed address) + handler: handleConversionResumed + - event: ConverterNetworkAddressUpdated(indexed address,indexed address) + handler: handleConverterNetworkAddressUpdated + - event: DestinationAddressUpdated(indexed address,indexed address) + handler: handleDestinationAddressUpdated + - event: BaseAssetUpdated(indexed address,indexed address) + handler: handleBaseAssetUpdated + - event: PriceOracleUpdated(indexed address,indexed address) + handler: handlePriceOracleUpdated + - event: ConvertedExactTokens(indexed address,indexed address,address,indexed address,uint256,uint256) + handler: handleConvertedExactTokens + - event: ConvertedForExactTokens(indexed address,indexed address,address,indexed address,uint256,uint256) + handler: handleConversionEvent + - event: ConvertedExactTokensSupportingFeeOnTransferTokens(indexed address,indexed address,address,indexed address,uint256,uint256) + handler: handleConversionEvent + - event: ConvertedForExactTokensSupportingFeeOnTransferTokens(indexed address,indexed address,address,indexed address,uint256,uint256) + handler: handleConversionEvent + - event: AssetTransferredToDestination(indexed address,indexed address,indexed address,uint256) + handler: handleAssetTransferredToDestination + blockHandlers: + - handler: handleInitializationWBnbBurnConverter + filter: + kind: once templates: - name: ERC20 kind: ethereum/contract @@ -290,7 +400,7 @@ templates: eventHandlers: - event: Transfer(indexed address,indexed address,uint256) handler: handleTransferOut - topic1: ["{{ xvsVaultConverterAddress }}", "{{ btcbPrimeConverterAddress }}", "{{ ethPrimeConverterAddress }}", "{{ riskFundConverterAddress }}", "{{ usdcPrimeConverterAddress }}", "{{ usdtPrimeConverterAddress }}"] + topic1: ["{{ xvsVaultConverterAddress }}", "{{ btcbPrimeConverterAddress }}", "{{ ethPrimeConverterAddress }}", "{{ riskFundConverterAddress }}", "{{ usdcPrimeConverterAddress }}", "{{ usdtPrimeConverterAddress }}", "{{ wBnbBurnConverterAddress}}"] - event: Transfer(indexed address,indexed address,uint256) handler: handleTransferIn - topic2: ["{{ xvsVaultConverterAddress }}", "{{ btcbPrimeConverterAddress }}", "{{ ethPrimeConverterAddress }}", "{{ riskFundConverterAddress }}", "{{ usdcPrimeConverterAddress }}", "{{ usdtPrimeConverterAddress }}"] + topic2: ["{{ xvsVaultConverterAddress }}", "{{ btcbPrimeConverterAddress }}", "{{ ethPrimeConverterAddress }}", "{{ riskFundConverterAddress }}", "{{ usdcPrimeConverterAddress }}", "{{ usdtPrimeConverterAddress }}", "{{ wBnbBurnConverterAddress}}"] diff --git a/subgraphs/protocol-reserve/tests/TokenConverter/events.ts b/subgraphs/protocol-reserve/tests/TokenConverter/events.ts index d2e2a1ce..1e487822 100644 --- a/subgraphs/protocol-reserve/tests/TokenConverter/events.ts +++ b/subgraphs/protocol-reserve/tests/TokenConverter/events.ts @@ -2,7 +2,9 @@ import { Address, BigInt, ethereum } from '@graphprotocol/graph-ts'; import { newMockEvent } from 'matchstick-as'; import { + AssetTransferredToDestination, BaseAssetUpdated, + ConvertedExactTokens, ConversionConfigUpdated, ConversionPaused, ConversionResumed, @@ -148,3 +150,81 @@ export const createBaseAssetUpdatedEvent = ( return event; }; + +export const createConvertedEvent = ( + tokenConverterAddress: Address, + sender: Address, + receiver: Address, + tokenAddressIn: Address, + tokenAddressOut: Address, + amountIn: string, + amountOut: string, +): ConvertedExactTokens => { + const event = changetype(newMockEvent()); + event.address = tokenConverterAddress; + event.parameters = []; + + const senderParam = new ethereum.EventParam('sender', ethereum.Value.fromAddress(sender)); + event.parameters.push(senderParam); + + const receiverParam = new ethereum.EventParam('receiver', ethereum.Value.fromAddress(receiver)); + event.parameters.push(receiverParam); + + const tokenAddressInParam = new ethereum.EventParam( + 'tokenAddressIn', + ethereum.Value.fromAddress(tokenAddressIn), + ); + event.parameters.push(tokenAddressInParam); + + const tokenAddressOutParam = new ethereum.EventParam( + 'tokenAddressOut', + ethereum.Value.fromAddress(tokenAddressOut), + ); + event.parameters.push(tokenAddressOutParam); + + const amountInParam = new ethereum.EventParam( + 'amountIn', + ethereum.Value.fromUnsignedBigInt(BigInt.fromString(amountIn)), + ); + event.parameters.push(amountInParam); + + const amountOutParam = new ethereum.EventParam( + 'amountOut', + ethereum.Value.fromUnsignedBigInt(BigInt.fromString(amountOut)), + ); + event.parameters.push(amountOutParam); + + return event; +}; + +export const createAssetTransferredToDestinationEvent = ( + tokenConverterAddress: Address, + receiver: Address, + comptroller: Address, + asset: Address, + amount: string, +): AssetTransferredToDestination => { + const event = changetype(newMockEvent()); + event.address = tokenConverterAddress; + event.parameters = []; + + const receiverParam = new ethereum.EventParam('receiver', ethereum.Value.fromAddress(receiver)); + event.parameters.push(receiverParam); + + const comptrollerParam = new ethereum.EventParam( + 'comptroller', + ethereum.Value.fromAddress(comptroller), + ); + event.parameters.push(comptrollerParam); + + const assetParam = new ethereum.EventParam('asset', ethereum.Value.fromAddress(asset)); + event.parameters.push(assetParam); + + const amountParam = new ethereum.EventParam( + 'amount', + ethereum.Value.fromUnsignedBigInt(BigInt.fromString(amount)), + ); + event.parameters.push(amountParam); + + return event; +}; diff --git a/subgraphs/protocol-reserve/tests/TokenConverter/index.test.ts b/subgraphs/protocol-reserve/tests/TokenConverter/index.test.ts index d2c9dae6..1c9955e7 100644 --- a/subgraphs/protocol-reserve/tests/TokenConverter/index.test.ts +++ b/subgraphs/protocol-reserve/tests/TokenConverter/index.test.ts @@ -1,10 +1,12 @@ -import { Address } from '@graphprotocol/graph-ts'; +import { Address, BigInt } from '@graphprotocol/graph-ts'; import { assert, beforeAll, describe, test } from 'matchstick-as/assembly/index'; import { TokenConverter } from '../../generated/schema'; import { + handleAssetTransferredToDestination, handleBaseAssetUpdated, handleConversionConfigUpdated, + handleConversionEvent, handleConversionPaused, handleConversionResumed, handleConverterNetworkAddressUpdated, @@ -17,7 +19,9 @@ import { createConversionPausedEvent, createConversionResumedEvent, createConverterNetworkAddressUpdatedEvent, + createConvertedEvent, createDestinationAddressUpdatedEvent, + createAssetTransferredToDestinationEvent, } from './events'; import { createTokenConverterMock, createTokenMock } from './mocks'; @@ -170,4 +174,52 @@ describe('Token Converter', () => { token4Address.toHexString(), ); }); + + test('should handle a "converted" event', () => { + handleConversionEvent( + createConvertedEvent( + tokenConverter2Address, + user, + user, + token1Address, + token2Address, + '1', + '2', + ), + ); + + const tokenConverter = TokenConverter.load(getTokenConverterId(tokenConverter2Address))!; + const destinationAmounts = tokenConverter.destinationAmounts.load(); + assert.i32Equals(destinationAmounts.length, 1); + assert.bigIntEquals(destinationAmounts[0].amount, BigInt.fromString('1')); + assert.addressEquals(Address.fromBytes(destinationAmounts[0].token), token1Address); + assert.addressEquals(Address.fromBytes(destinationAmounts[0].address), destination2Address); + assert.addressEquals( + Address.fromBytes(destinationAmounts[0].tokenConverter), + tokenConverter2Address, + ); + }); + + test('should handle an AssetTransferredToDestination event', () => { + handleAssetTransferredToDestination( + createAssetTransferredToDestinationEvent( + tokenConverter2Address, + destination1Address, + Address.fromString('0x0000000000000000000000000000000000000bca'), + token2Address, + '12345', + ), + ); + + const tokenConverter = TokenConverter.load(getTokenConverterId(tokenConverter2Address))!; + const destinationAmounts = tokenConverter.destinationAmounts.load(); + assert.i32Equals(destinationAmounts.length, 2); + assert.bigIntEquals(destinationAmounts[1].amount, BigInt.fromString('12345')); + assert.addressEquals(Address.fromBytes(destinationAmounts[1].token), token2Address); + assert.addressEquals(Address.fromBytes(destinationAmounts[1].address), destination1Address); + assert.addressEquals( + Address.fromBytes(destinationAmounts[1].tokenConverter), + tokenConverter2Address, + ); + }); }); diff --git a/yarn.lock b/yarn.lock index c0c96eb7..274e75a6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1138,6 +1138,27 @@ __metadata: languageName: node linkType: hard +"@defi-wonderland/smock@npm:2.4.0": + version: 2.4.0 + resolution: "@defi-wonderland/smock@npm:2.4.0" + dependencies: + "@nomicfoundation/ethereumjs-util": ^9.0.4 + diff: ^5.0.0 + lodash.isequal: ^4.5.0 + lodash.isequalwith: ^4.4.0 + rxjs: ^7.2.0 + semver: ^7.3.5 + peerDependencies: + "@ethersproject/abi": ^5 + "@ethersproject/abstract-provider": ^5 + "@ethersproject/abstract-signer": ^5 + "@nomiclabs/hardhat-ethers": ^2 + ethers: ^5 + hardhat: ^2.21.0 + checksum: 421f97cfa9a8f7bbdafc6521723f5ed0c3b7cd0462dc7d1a143a2de9cbdac46dd6acd7db619aa03a09d62695c5337fb17699259db2d5e4ddb530f5f55ef4ef30 + languageName: node + linkType: hard + "@envelop/core@npm:^3.0.4, @envelop/core@npm:^3.0.6": version: 3.0.6 resolution: "@envelop/core@npm:3.0.6" @@ -3500,7 +3521,7 @@ __metadata: languageName: node linkType: hard -"@nomicfoundation/edr@npm:^0.6.5": +"@nomicfoundation/edr@npm:^0.6.4, @nomicfoundation/edr@npm:^0.6.5": version: 0.6.5 resolution: "@nomicfoundation/edr@npm:0.6.5" dependencies: @@ -3819,7 +3840,7 @@ __metadata: languageName: node linkType: hard -"@nomicfoundation/ethereumjs-util@npm:9.0.4": +"@nomicfoundation/ethereumjs-util@npm:9.0.4, @nomicfoundation/ethereumjs-util@npm:^9.0.4": version: 9.0.4 resolution: "@nomicfoundation/ethereumjs-util@npm:9.0.4" dependencies: @@ -5742,9 +5763,9 @@ __metadata: languageName: node linkType: hard -"@venusprotocol/isolated-pools@npm:^3.4.0": - version: 3.9.0 - resolution: "@venusprotocol/isolated-pools@npm:3.9.0" +"@venusprotocol/isolated-pools@npm:^4.0.0": + version: 4.2.0 + resolution: "@venusprotocol/isolated-pools@npm:4.2.0" dependencies: "@nomiclabs/hardhat-ethers": ^2.2.3 "@openzeppelin/contracts": ^4.8.3 @@ -5755,7 +5776,7 @@ __metadata: ethers: ^5.7.0 hardhat-deploy: ^0.11.14 module-alias: ^2.2.2 - checksum: f72d664e73667aff1ad773bf7464f07110f1a7a150efe31e59805ef92c58c94405cfcefef15983182c339f3812365b72f9ac8fdd13ddd6876e1c0ef9739cc4d2 + checksum: 95e907e9aefaad460793b79a2817cdf0897bb61d0999b813a2cadd20105ca583f6cc544895b5597d8f14739cb6d41175d825aae588d6b0a46963af337ca344d2 languageName: node linkType: hard @@ -5780,24 +5801,25 @@ __metadata: languageName: node linkType: hard -"@venusprotocol/oracle@npm:^2.7.0": - version: 2.7.0 - resolution: "@venusprotocol/oracle@npm:2.7.0" +"@venusprotocol/oracle@npm:^2.12.0": + version: 2.12.0 + resolution: "@venusprotocol/oracle@npm:2.12.0" dependencies: "@chainlink/contracts": ^0.5.1 - "@defi-wonderland/smock": 2.3.5 + "@defi-wonderland/smock": 2.4.0 "@nomicfoundation/hardhat-network-helpers": ^1.0.8 "@openzeppelin/contracts": ^4.6.0 "@openzeppelin/contracts-upgradeable": ^4.7.3 - "@venusprotocol/governance-contracts": ^2.4.0 + "@venusprotocol/governance-contracts": ^2.9.0 "@venusprotocol/solidity-utilities": ^2.0.0 - "@venusprotocol/venus-protocol": ^9.1.0 + "@venusprotocol/venus-protocol": ^9.7.0 ethers: ^5.6.8 - hardhat: 2.19.5 + hardhat: 2.22.15 hardhat-deploy: ^0.12.4 module-alias: ^2.2.2 + patch-package: ^8.0.0 solidity-docgen: ^0.6.0-beta.29 - checksum: 1fd036da69399b2d7024958bf12e07b053be553d0ba136334035b055b691a2b3b748dd6f52f6756c9770a216df8a8915a0e1a49d7169efcd1c658a21107e2ba4 + checksum: 26b9b09878aa6cbc2fa677f3710dddf20ce760fb746b9ef8c0287a8dc88b7023ce6ff3e4380b918484ad2c698fac3de1ce45d4cc3d6cb50647081460843ca303 languageName: node linkType: hard @@ -5816,24 +5838,24 @@ __metadata: languageName: unknown linkType: soft -"@venusprotocol/protocol-reserve@npm:3.1.0": - version: 3.1.0 - resolution: "@venusprotocol/protocol-reserve@npm:3.1.0" +"@venusprotocol/protocol-reserve@npm:3.4.0-dev.3": + version: 3.4.0-dev.3 + resolution: "@venusprotocol/protocol-reserve@npm:3.4.0-dev.3" dependencies: "@nomiclabs/hardhat-ethers": ^2.2.3 "@openzeppelin/contracts": ^4.8.3 "@openzeppelin/contracts-upgradeable": ^4.8.3 "@openzeppelin/hardhat-upgrades": ^1.21.0 "@solidity-parser/parser": ^0.13.2 - "@venusprotocol/governance-contracts": ^2.8.0 - "@venusprotocol/isolated-pools": ^3.4.0 - "@venusprotocol/oracle": ^2.7.0 + "@venusprotocol/governance-contracts": ^2.10.0 + "@venusprotocol/isolated-pools": ^4.0.0 + "@venusprotocol/oracle": ^2.12.0 "@venusprotocol/solidity-utilities": ^2.0.3 - "@venusprotocol/venus-protocol": ^9.1.0 + "@venusprotocol/venus-protocol": ^9.7.0 ethers: ^5.7.0 hardhat-deploy: ^0.14.0 module-alias: ^2.2.2 - checksum: b23d664c7384113ef17080848a454ead20ddab04b377be8994057c6018ccdfa4152d37693f6b51d2805686f2b8fc8b8b960b3f24995459846150ffff28dd5bc8 + checksum: f01763a88f18ea9756a3b589afc3c17f96c7e5db9eaa7dfd7992c8354ac1f85feafd067c749bd53d84fde13e095421ff633904e58d6ce289602987355efcf206 languageName: node linkType: hard @@ -5889,7 +5911,7 @@ __metadata: "@venusprotocol/governance-contracts": 2.10.0 "@venusprotocol/isolated-pools": 4.2.0-dev.9 "@venusprotocol/oracle": 2.9.0 - "@venusprotocol/protocol-reserve": 3.1.0 + "@venusprotocol/protocol-reserve": 3.4.0-dev.3 "@venusprotocol/solidity-utilities": ^2.0.3 "@venusprotocol/venus-protocol": 9.6.0 assemblyscript: 0.19.23 @@ -7245,6 +7267,16 @@ __metadata: languageName: node linkType: hard +"call-bind-apply-helpers@npm:^1.0.2": + version: 1.0.2 + resolution: "call-bind-apply-helpers@npm:1.0.2" + dependencies: + es-errors: ^1.3.0 + function-bind: ^1.1.2 + checksum: b2863d74fcf2a6948221f65d95b91b4b2d90cfe8927650b506141e669f7d5de65cea191bf788838bc40d13846b7886c5bc5c84ab96c3adbcf88ad69a72fcdc6b + languageName: node + linkType: hard + "call-bind@npm:^1.0.5, call-bind@npm:^1.0.6, call-bind@npm:^1.0.7, call-bind@npm:^1.0.8": version: 1.0.8 resolution: "call-bind@npm:1.0.8" @@ -7267,6 +7299,16 @@ __metadata: languageName: node linkType: hard +"call-bound@npm:^1.0.4": + version: 1.0.4 + resolution: "call-bound@npm:1.0.4" + dependencies: + call-bind-apply-helpers: ^1.0.2 + get-intrinsic: ^1.3.0 + checksum: 2f6399488d1c272f56306ca60ff696575e2b7f31daf23bc11574798c84d9f2759dceb0cb1f471a85b77f28962a7ac6411f51d283ea2e45319009a19b6ccab3b2 + languageName: node + linkType: hard + "caller-callsite@npm:^2.0.0": version: 2.0.0 resolution: "caller-callsite@npm:2.0.0" @@ -7630,6 +7672,13 @@ __metadata: languageName: node linkType: hard +"ci-info@npm:^3.7.0": + version: 3.9.0 + resolution: "ci-info@npm:3.9.0" + checksum: 6b19dc9b2966d1f8c2041a838217299718f15d6c4b63ae36e4674edd2bee48f780e94761286a56aa59eb305a85fbea4ddffb7630ec063e7ec7e7e5ad42549a87 + languageName: node + linkType: hard + "ci-info@npm:^4.0.0, ci-info@npm:^4.1.0": version: 4.1.0 resolution: "ci-info@npm:4.1.0" @@ -8732,7 +8781,7 @@ __metadata: languageName: node linkType: hard -"dunder-proto@npm:^1.0.0": +"dunder-proto@npm:^1.0.0, dunder-proto@npm:^1.0.1": version: 1.0.1 resolution: "dunder-proto@npm:1.0.1" dependencies: @@ -9025,6 +9074,15 @@ __metadata: languageName: node linkType: hard +"es-object-atoms@npm:^1.1.1": + version: 1.1.1 + resolution: "es-object-atoms@npm:1.1.1" + dependencies: + es-errors: ^1.3.0 + checksum: 214d3767287b12f36d3d7267ef342bbbe1e89f899cfd67040309fc65032372a8e60201410a99a1645f2f90c1912c8c49c8668066f6bdd954bcd614dda2e3da97 + languageName: node + linkType: hard + "es-set-tostringtag@npm:^2.0.3": version: 2.0.3 resolution: "es-set-tostringtag@npm:2.0.3" @@ -10230,6 +10288,24 @@ __metadata: languageName: node linkType: hard +"get-intrinsic@npm:^1.3.0": + version: 1.3.0 + resolution: "get-intrinsic@npm:1.3.0" + dependencies: + call-bind-apply-helpers: ^1.0.2 + es-define-property: ^1.0.1 + es-errors: ^1.3.0 + es-object-atoms: ^1.1.1 + function-bind: ^1.1.2 + get-proto: ^1.0.1 + gopd: ^1.2.0 + has-symbols: ^1.1.0 + hasown: ^2.0.2 + math-intrinsics: ^1.1.0 + checksum: 301008e4482bb9a9cb49e132b88fee093bff373b4e6def8ba219b1e96b60158a6084f273ef5cafe832e42cd93462f4accb46a618d35fe59a2b507f2388c5b79d + languageName: node + linkType: hard + "get-iterator@npm:^1.0.2": version: 1.0.2 resolution: "get-iterator@npm:1.0.2" @@ -10251,6 +10327,16 @@ __metadata: languageName: node linkType: hard +"get-proto@npm:^1.0.1": + version: 1.0.1 + resolution: "get-proto@npm:1.0.1" + dependencies: + dunder-proto: ^1.0.1 + es-object-atoms: ^1.0.0 + checksum: 4fc96afdb58ced9a67558698b91433e6b037aaa6f1493af77498d7c85b141382cf223c0e5946f334fb328ee85dfe6edd06d218eaf09556f4bc4ec6005d7f5f7b + languageName: node + linkType: hard + "get-stdin@npm:^6.0.0": version: 6.0.0 resolution: "get-stdin@npm:6.0.0" @@ -10961,6 +11047,68 @@ __metadata: languageName: node linkType: hard +"hardhat@npm:2.22.15": + version: 2.22.15 + resolution: "hardhat@npm:2.22.15" + dependencies: + "@ethersproject/abi": ^5.1.2 + "@metamask/eth-sig-util": ^4.0.0 + "@nomicfoundation/edr": ^0.6.4 + "@nomicfoundation/ethereumjs-common": 4.0.4 + "@nomicfoundation/ethereumjs-tx": 5.0.4 + "@nomicfoundation/ethereumjs-util": 9.0.4 + "@nomicfoundation/solidity-analyzer": ^0.1.0 + "@sentry/node": ^5.18.1 + "@types/bn.js": ^5.1.0 + "@types/lru-cache": ^5.1.0 + adm-zip: ^0.4.16 + aggregate-error: ^3.0.0 + ansi-escapes: ^4.3.0 + boxen: ^5.1.2 + chalk: ^2.4.2 + chokidar: ^4.0.0 + ci-info: ^2.0.0 + debug: ^4.1.1 + enquirer: ^2.3.0 + env-paths: ^2.2.0 + ethereum-cryptography: ^1.0.3 + ethereumjs-abi: ^0.6.8 + find-up: ^2.1.0 + fp-ts: 1.19.3 + fs-extra: ^7.0.1 + glob: 7.2.0 + immutable: ^4.0.0-rc.12 + io-ts: 1.10.4 + json-stream-stringify: ^3.1.4 + keccak: ^3.0.2 + lodash: ^4.17.11 + mnemonist: ^0.38.0 + mocha: ^10.0.0 + p-map: ^4.0.0 + raw-body: ^2.4.1 + resolve: 1.17.0 + semver: ^6.3.0 + solc: 0.8.26 + source-map-support: ^0.5.13 + stacktrace-parser: ^0.1.10 + tsort: 0.0.1 + undici: ^5.14.0 + uuid: ^8.3.2 + ws: ^7.4.6 + peerDependencies: + ts-node: "*" + typescript: "*" + peerDependenciesMeta: + ts-node: + optional: true + typescript: + optional: true + bin: + hardhat: internal/cli/bootstrap.js + checksum: 214f0bf9b8a7cb90d5be906e49adf7da87df0d10db42cc7a48ccc1129cda11da8578fe12bbb30a1e5f2c5d9e96a7733a4750626abd602e0a263a8d1f366a4f9a + languageName: node + linkType: hard + "hardhat@npm:^2.10.2, hardhat@npm:^2.16.1, hardhat@npm:^2.8.0": version: 2.22.17 resolution: "hardhat@npm:2.22.17" @@ -12590,6 +12738,19 @@ __metadata: languageName: node linkType: hard +"json-stable-stringify@npm:^1.0.2": + version: 1.3.0 + resolution: "json-stable-stringify@npm:1.3.0" + dependencies: + call-bind: ^1.0.8 + call-bound: ^1.0.4 + isarray: ^2.0.5 + jsonify: ^0.0.1 + object-keys: ^1.1.1 + checksum: aaa8b56b7dbee2234adc5e318cf71e38ecd7b8a3811a420a77add8c870d281f7f5050008e2964a7ced4857f501f4667f3ac88b44bf70197bd0682e068a4d93ea + languageName: node + linkType: hard + "json-stream-stringify@npm:^3.1.4": version: 3.1.6 resolution: "json-stream-stringify@npm:3.1.6" @@ -12668,6 +12829,13 @@ __metadata: languageName: node linkType: hard +"jsonify@npm:^0.0.1": + version: 0.0.1 + resolution: "jsonify@npm:0.0.1" + checksum: 027287e1c0294fce15f18c0ff990cfc2318e7f01fb76515f784d5cd0784abfec6fc5c2355c3a2f2cb0ad7f4aa2f5b74ebbfe4e80476c35b2d13cabdb572e1134 + languageName: node + linkType: hard + "jsonparse@npm:^1.2.0, jsonparse@npm:^1.3.1": version: 1.3.1 resolution: "jsonparse@npm:1.3.1" @@ -13492,6 +13660,13 @@ __metadata: languageName: node linkType: hard +"math-intrinsics@npm:^1.1.0": + version: 1.1.0 + resolution: "math-intrinsics@npm:1.1.0" + checksum: 0e513b29d120f478c85a70f49da0b8b19bc638975eca466f2eeae0071f3ad00454c621bf66e16dd435896c208e719fc91ad79bbfba4e400fe0b372e7c1c9c9a2 + languageName: node + linkType: hard + "mcl-wasm@npm:^0.7.1": version: 0.7.9 resolution: "mcl-wasm@npm:0.7.9" @@ -15095,6 +15270,31 @@ __metadata: languageName: node linkType: hard +"patch-package@npm:^8.0.0": + version: 8.0.0 + resolution: "patch-package@npm:8.0.0" + dependencies: + "@yarnpkg/lockfile": ^1.1.0 + chalk: ^4.1.2 + ci-info: ^3.7.0 + cross-spawn: ^7.0.3 + find-yarn-workspace-root: ^2.0.0 + fs-extra: ^9.0.0 + json-stable-stringify: ^1.0.2 + klaw-sync: ^6.0.0 + minimist: ^1.2.6 + open: ^7.4.2 + rimraf: ^2.6.3 + semver: ^7.5.3 + slash: ^2.0.0 + tmp: ^0.0.33 + yaml: ^2.2.2 + bin: + patch-package: index.js + checksum: d23cddc4d1622e2d8c7ca31b145c6eddb24bd271f69905e766de5e1f199f0b9a5479a6a6939ea857288399d4ed249285639d539a2c00fbddb7daa39934b007a2 + languageName: node + linkType: hard + "path-browserify@npm:1.0.1": version: 1.0.1 resolution: "path-browserify@npm:1.0.1" @@ -18693,6 +18893,15 @@ __metadata: languageName: node linkType: hard +"yaml@npm:^2.2.2": + version: 2.8.0 + resolution: "yaml@npm:2.8.0" + bin: + yaml: bin.mjs + checksum: 66f103ca5a2f02dac0526895cc7ae7626d91aa8c43aad6fdcff15edf68b1199be4012140b390063877913441aaa5288fdf57eca30e06268a8282dd741525e626 + languageName: node + linkType: hard + "yargs-parser@npm:^18.1.2": version: 18.1.3 resolution: "yargs-parser@npm:18.1.3"