Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ handler({
testGasCost: false,
urlNetwork: "https://ocean.defichain.com/",
envNetwork: EnvironmentNetwork.MainNet,
contractAddress: /* YOUR STATE RELAYER PROXY ADDRESS */,
signer: /* signer object */,
gasUpdateDEX: /* gas limit for dex update transaction */,
gasUpdateMaster: /* gas limit for master node update transaction */,
gasUpdateVault: /* gas limit for vault update transaction */
contractAddress: "" /* YOUR STATE RELAYER PROXY ADDRESS */,
signer: "" /* signer object */,
gasUpdateDEX: "" /* gas limit for dex update transaction */,
gasUpdateMaster: "" /* gas limit for master node update transaction */,
gasUpdateVault: "" /* gas limit for vault update transaction */,
gasUpdateOracle: "" /* gas limit for oracle update transaction */,
})
```

Expand Down
28 changes: 25 additions & 3 deletions bot/StateRelayerBot.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import { ApiPagedResponse } from '@defichain/whale-api-client';
import { PoolPairData } from '@defichain/whale-api-client/dist/api/poolpairs';
import { PriceTicker } from '@defichain/whale-api-client/dist/api/prices';
import { getWhaleClient } from '@waveshq/walletkit-bot';
import { ethers } from 'ethers';

import { StateRelayer__factory } from '../generated';
import { tranformPairData, transformDataMasternode, transformDataVault } from './utils/transformData';
import { StateRelayerV2__factory } from '../generated';
import { tranformPairData, transformDataMasternode, transformDataVault, transformOracleData } from './utils/transformData';
import { DataStore, MasterNodeData, StateRelayerHandlerProps, VaultData } from './utils/types';

const DENOMINATION = 'USDT';
const PAGESIZE = 50;

export async function handler(props: StateRelayerHandlerProps): Promise<DFCData | undefined> {
const { urlNetwork, envNetwork, signer, contractAddress } = props;
const stateRelayerContract = StateRelayer__factory.connect(contractAddress, signer);
const stateRelayerContract = StateRelayerV2__factory.connect(contractAddress, signer);
const dataStore = {} as DataStore;
try {
// TODO: Check if Function should run (blockHeight > 30 from previous)
Expand Down Expand Up @@ -71,6 +72,17 @@ export async function handler(props: StateRelayerHandlerProps): Promise<DFCData

const inputForDexUpdate = tranformPairData(rawPoolPairData, statsData, dexPriceData);

// Data for Oracles
let rawPriceData: Array<PriceTicker> = [];
let pagedPriceData: ApiPagedResponse<PriceTicker> = await client.prices.list(PAGESIZE);
rawPriceData = rawPriceData.concat(pagedPriceData);
while (pagedPriceData.hasNext) {
pagedPriceData = await client.paginate(pagedPriceData);
rawPriceData = rawPriceData.concat(pagedPriceData);
}

const inputForOracleUpdate = transformOracleData(rawPriceData)

// Data from vaults
const dataVault = transformDataVault(statsData);

Expand Down Expand Up @@ -99,9 +111,17 @@ export async function handler(props: StateRelayerHandlerProps): Promise<DFCData
gasLimit: props.gasUpdateVault,
});

// Update Oracle information
const oracleInfoTx = await stateRelayerContract.updateOracleInfo(
inputForOracleUpdate.oracle,
inputForOracleUpdate.oracleInfo,
{ nonce: nonce + 3, gasLimit: props.gasUpdateOracle },
);

console.log('Hash of dex update transaction', dexInfoTx.hash);
console.log('Hash of master update transaction', masterDataTx.hash);
console.log('Hash of vault update transaction', vaultTx.hash);
console.log('Hash of oracle update transaction', oracleInfoTx.hash);

if (!props.testGasCost) {
return {
Expand All @@ -117,6 +137,7 @@ export async function handler(props: StateRelayerHandlerProps): Promise<DFCData
dexInfoTxReceipt: (await dexInfoTx.wait()) || undefined,
masterDataTxReceipt: (await masterDataTx.wait()) || undefined,
vaultTxReceipt: (await vaultTx.wait()) || undefined,
oracleInfoTxReceipt: (await oracleInfoTx.wait()) || undefined,
};
} catch (e) {
console.error((e as Error).message);
Expand All @@ -131,4 +152,5 @@ interface DFCData {
dexInfoTxReceipt?: ethers.ContractTransactionReceipt;
masterDataTxReceipt?: ethers.ContractTransactionReceipt;
vaultTxReceipt?: ethers.ContractTransactionReceipt;
oracleInfoTxReceipt?: ethers.ContractTransactionReceipt;
}
38 changes: 34 additions & 4 deletions bot/test-i9n/StateRelayerBot.unit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ import { EnvironmentNetwork } from '@waveshq/walletkit-core';
import { ethers } from 'ethers';

import { HardhatNetwork, HardhatNetworkContainer, StartedHardhatNetworkContainer } from '../../containers';
import { StateRelayer, StateRelayer__factory, StateRelayerProxy__factory } from '../../generated';
import { StateRelayer__factory, StateRelayerProxy__factory, StateRelayerV2, StateRelayerV2__factory } from '../../generated';
import { handler } from '../StateRelayerBot';
import { tranformPairData } from '../utils/transformData';
import { tranformPairData, transformOracleData } from '../utils/transformData';
import {
expectedMasterNodeData,
expectedVaultData,
mockedDexPricesData,
mockedPoolPairData,
mockedPriceData,
mockedStatsData,
} from './mockData/oceanMockedData';

Expand All @@ -23,6 +24,9 @@ jest.mock('@defichain/whale-api-client', () => ({
list: () => mockedPoolPairData,
listDexPrices: () => mockedDexPricesData,
},
prices: {
list: () => mockedPriceData
}
})),
}));

Expand All @@ -31,7 +35,7 @@ describe('State Relayer Bot Tests', () => {
let hardhatNetwork: HardhatNetwork;
let admin: ethers.Signer;
let bot: ethers.Signer;
let proxy: StateRelayer;
let proxy: StateRelayerV2;

beforeEach(async () => {
startedHardhatContainer = await new HardhatNetworkContainer()
Expand Down Expand Up @@ -59,7 +63,23 @@ describe('State Relayer Bot Tests', () => {
]),
],
});
proxy = StateRelayer__factory.connect((await stateRelayerProxy?.getAddress()) || '', bot);
// update v2
const stateRelayerV2Implementation = await hardhatNetwork?.contracts?.deployContract({
deploymentName: 'StateRelayerImplementationV2',
contractName: 'StateRelayerV2',
abi: StateRelayerV2__factory.abi,
});
const encodedData = StateRelayerV2__factory.createInterface().encodeFunctionData("initialize", [
// Contract version
2,
]);

// Upgrading the Proxy contract
const stateRelayerV2Address = await stateRelayerV2Implementation?.getAddress() ?? "";
const v1Contract = StateRelayer__factory.connect((await stateRelayerProxy?.getAddress()) || '', bot);

await v1Contract?.connect(admin)?.upgradeToAndCall(stateRelayerV2Address, encodedData)
proxy = StateRelayerV2__factory.connect((await stateRelayerProxy?.getAddress()) || '', bot);
});

afterEach(async () => {
Expand Down Expand Up @@ -103,6 +123,16 @@ describe('State Relayer Bot Tests', () => {
expect(dex[2]).toStrictEqual(expectedDexInfo.totalValueLocked);
expect(dex[1]).toStrictEqual(expectedDexInfo.total24HVolume);

// Checking the oracle info
const testOceanData = await client.prices.list(200);
const dTSLA = await proxy.getOraclePairInfo('TSLA-USD');
const expectedOracleInfo = transformOracleData(testOceanData);
const lastTSLAUSDInfo = expectedOracleInfo.oracleInfo[expectedOracleInfo.oracle.indexOf('TSLA-USD')];
// for sure both two sides have the same type as bigint
expect(dTSLA[1].price).toStrictEqual(lastTSLAUSDInfo.price);
expect(dTSLA[1].oraclesActive).toStrictEqual(lastTSLAUSDInfo.oraclesActive);
expect(dTSLA[1].oraclesTotal).toStrictEqual(lastTSLAUSDInfo.oraclesTotal);

// Checking MasterNode information
const receivedMasterNodeData = await proxy.getMasterNodeInfo();
expect(receivedMasterNodeData[1].totalValueLockedInMasterNodes).toStrictEqual(
Expand Down
Loading