Skip to content

Commit

Permalink
Entropy support in contract manager (#1242)
Browse files Browse the repository at this point in the history
* Rename contracts to PriceFeedContracts

* Initial version of EvmEntropyContract
  • Loading branch information
m30m authored Jan 24, 2024
1 parent 70c6db0 commit eef8468
Show file tree
Hide file tree
Showing 23 changed files with 286 additions and 191 deletions.
1 change: 1 addition & 0 deletions contract_manager/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"@injectivelabs/networks": "1.0.68",
"@mysten/sui.js": "^0.37.1",
"@pythnetwork/cosmwasm-deploy-tools": "*",
"@pythnetwork/entropy-sdk-solidity": "*",
"@pythnetwork/price-service-client": "*",
"@pythnetwork/pyth-sui-js": "*",
"aptos": "^1.5.0",
Expand Down
11 changes: 7 additions & 4 deletions contract_manager/scripts/check_proposal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ import {
} from "@pythnetwork/client/lib/cluster";
import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet";
import { AccountMeta, Keypair, PublicKey } from "@solana/web3.js";
import { EvmContract, WormholeEvmContract } from "../src/contracts/evm";
import {
EvmPriceFeedContract,
WormholeEvmContract,
} from "../src/contracts/evm";
import Web3 from "web3";

const parser = yargs(hideBin(process.argv))
Expand Down Expand Up @@ -71,11 +74,11 @@ async function main() {
const currentIndex = await contract.getCurrentGuardianSetIndex();
const guardianSet = await contract.getGuardianSet();

const proxyContract = new EvmContract(chain, address);
const proxyContract = new EvmPriceFeedContract(chain, address);
const proxyCode = await proxyContract.getCode();
const receiverImplementation =
await proxyContract.getImplementationAddress();
const implementationCode = await new EvmContract(
const implementationCode = await new EvmPriceFeedContract(
chain,
receiverImplementation
).getCode();
Expand Down Expand Up @@ -103,7 +106,7 @@ async function main() {
instruction.governanceAction.targetChainId
) {
const address = instruction.governanceAction.address;
const contract = new EvmContract(chain, address);
const contract = new EvmPriceFeedContract(chain, address);
const code = await contract.getCodeDigestWithoutAddress();
// this should be the same keccak256 of the deployedCode property generated by truffle
console.log(`${chain.getId()} Address:${address} digest:${code}`);
Expand Down
4 changes: 2 additions & 2 deletions contract_manager/scripts/deploy_cosmwasm.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import yargs from "yargs";
import { hideBin } from "yargs/helpers";
import { CosmWasmChain } from "../src/chains";
import { CosmWasmContract } from "../src/contracts/cosmwasm";
import { CosmWasmPriceFeedContract } from "../src/contracts/cosmwasm";
import { DefaultStore } from "../src/store";

const parser = yargs(hideBin(process.argv))
Expand Down Expand Up @@ -36,7 +36,7 @@ async function main() {
const argv = await parser.argv;
const { code, wormholeContract } = argv;
console.log(
await CosmWasmContract.deploy(
await CosmWasmPriceFeedContract.deploy(
DefaultStore.chains[argv.chain] as CosmWasmChain,
wormholeContract,
argv["private-key"],
Expand Down
12 changes: 6 additions & 6 deletions contract_manager/scripts/fetch_fees.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import yargs from "yargs";
import { hideBin } from "yargs/helpers";
import {
AptosContract,
CosmWasmContract,
AptosPriceFeedContract,
CosmWasmPriceFeedContract,
DefaultStore,
EvmContract,
EvmPriceFeedContract,
} from "../src";

const parser = yargs(hideBin(process.argv))
Expand All @@ -22,9 +22,9 @@ async function main() {
for (const contract of Object.values(DefaultStore.contracts)) {
if (contract.getChain().isMainnet() === argv.testnet) continue;
if (
contract instanceof AptosContract ||
contract instanceof EvmContract ||
contract instanceof CosmWasmContract
contract instanceof AptosPriceFeedContract ||
contract instanceof EvmPriceFeedContract ||
contract instanceof CosmWasmPriceFeedContract
) {
try {
console.log(`${contract.getId()} ${await contract.getTotalFee()}`);
Expand Down
9 changes: 5 additions & 4 deletions contract_manager/scripts/list_evm_contracts.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import yargs from "yargs";
import { hideBin } from "yargs/helpers";
import {
AptosContract,
CosmWasmContract,
AptosPriceFeedContract,
CosmWasmPriceFeedContract,
DefaultStore,
EvmContract,
EvmPriceFeedContract,
} from "../src";

const parser = yargs(hideBin(process.argv))
Expand All @@ -22,7 +22,8 @@ async function main() {
const entries = [];
for (const contract of Object.values(DefaultStore.contracts)) {
if (contract.getChain().isMainnet() === argv.testnet) continue;
if (contract instanceof EvmContract) {
if (contract instanceof EvmPriceFeedContract) {
let wormholeContract = await contract.getWormholeContract();
try {
const version = await contract.getVersion();
entries.push({
Expand Down
4 changes: 2 additions & 2 deletions contract_manager/scripts/upload_cosmwasm.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import yargs from "yargs";
import { hideBin } from "yargs/helpers";
import { CosmWasmChain } from "../src/chains";
import { CosmWasmContract } from "../src/contracts/cosmwasm";
import { CosmWasmPriceFeedContract } from "../src/contracts/cosmwasm";
import { DefaultStore } from "../src/store";
import { toPrivateKey } from "../src";

Expand Down Expand Up @@ -30,7 +30,7 @@ const parser = yargs(hideBin(process.argv))
async function main() {
const argv = await parser.argv;
const { code } = argv;
const { codeId } = await CosmWasmContract.storeCode(
const { codeId } = await CosmWasmPriceFeedContract.storeCode(
DefaultStore.chains[argv.chain] as CosmWasmChain,
toPrivateKey(argv["private-key"]),
code
Expand Down
2 changes: 1 addition & 1 deletion contract_manager/src/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export interface PriceFeed {
emaPrice: Price;
}

export abstract class Contract extends Storable {
export abstract class PriceFeedContract extends Storable {
/**
* Returns the time period in seconds that stale data is considered valid for.
*/
Expand Down
21 changes: 13 additions & 8 deletions contract_manager/src/contracts/aptos.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Contract, PriceFeed, PrivateKey, TxResult } from "../base";
import { PriceFeedContract, PriceFeed, PrivateKey, TxResult } from "../base";
import { ApiError, BCS, CoinClient, TxnBuilderTypes } from "aptos";
import { AptosChain, Chain } from "../chains";
import { DataSource } from "xc_admin_common";
Expand Down Expand Up @@ -70,8 +70,8 @@ export class WormholeAptosContract extends WormholeContract {
}
}

export class AptosContract extends Contract {
static type = "AptosContract";
export class AptosPriceFeedContract extends PriceFeedContract {
static type = "AptosPriceFeedContract";

/**
* Given the ids of the pyth state and wormhole state, create a new AptosContract
Expand All @@ -92,11 +92,16 @@ export class AptosContract extends Contract {
static fromJson(
chain: Chain,
parsed: { type: string; stateId: string; wormholeStateId: string }
): AptosContract {
if (parsed.type !== AptosContract.type) throw new Error("Invalid type");
): AptosPriceFeedContract {
if (parsed.type !== AptosPriceFeedContract.type)
throw new Error("Invalid type");
if (!(chain instanceof AptosChain))
throw new Error(`Wrong chain type ${chain}`);
return new AptosContract(chain, parsed.stateId, parsed.wormholeStateId);
return new AptosPriceFeedContract(
chain,
parsed.stateId,
parsed.wormholeStateId
);
}

async executeGovernanceInstruction(
Expand Down Expand Up @@ -252,7 +257,7 @@ export class AptosContract extends Contract {
}

getType(): string {
return AptosContract.type;
return AptosPriceFeedContract.type;
}

async getTotalFee(): Promise<bigint> {
Expand All @@ -272,7 +277,7 @@ export class AptosContract extends Contract {
chain: this.chain.getId(),
stateId: this.stateId,
wormholeStateId: this.wormholeStateId,
type: AptosContract.type,
type: AptosPriceFeedContract.type,
};
}
}
22 changes: 11 additions & 11 deletions contract_manager/src/contracts/cosmwasm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { Coin } from "@cosmjs/stargate";
import { DataSource } from "xc_admin_common";
import { CosmWasmClient } from "@cosmjs/cosmwasm-stargate";
import {
Contract,
PriceFeedContract,
getDefaultDeploymentConfig,
PrivateKey,
TxResult,
Expand Down Expand Up @@ -89,7 +89,8 @@ export class WormholeCosmWasmContract extends WormholeContract {
}
}

export class CosmWasmContract extends Contract {
export class CosmWasmPriceFeedContract extends PriceFeedContract {
static type = "CosmWasmPriceFeedContract";
async getDataSources(): Promise<DataSource[]> {
const config = await this.getConfig();
return config.config_v1.data_sources.map(
Expand All @@ -112,24 +113,23 @@ export class CosmWasmContract extends Contract {
};
}

static type = "CosmWasmContract";

constructor(public chain: CosmWasmChain, public address: string) {
super();
}

static fromJson(
chain: Chain,
parsed: { type: string; address: string }
): CosmWasmContract {
if (parsed.type !== CosmWasmContract.type) throw new Error("Invalid type");
): CosmWasmPriceFeedContract {
if (parsed.type !== CosmWasmPriceFeedContract.type)
throw new Error("Invalid type");
if (!(chain instanceof CosmWasmChain))
throw new Error(`Wrong chain type ${chain}`);
return new CosmWasmContract(chain, parsed.address);
return new CosmWasmPriceFeedContract(chain, parsed.address);
}

getType(): string {
return CosmWasmContract.type;
return CosmWasmPriceFeedContract.type;
}

/**
Expand Down Expand Up @@ -161,7 +161,7 @@ export class CosmWasmContract extends Contract {
codeId: number,
config: DeploymentConfig,
privateKey: PrivateKey
): Promise<CosmWasmContract> {
): Promise<CosmWasmPriceFeedContract> {
const executor = await chain.getExecutor(privateKey);
const result = await executor.instantiateContract({
codeId: codeId,
Expand All @@ -172,7 +172,7 @@ export class CosmWasmContract extends Contract {
newAdminAddr: result.contractAddr,
contractAddr: result.contractAddr,
});
return new CosmWasmContract(chain, result.contractAddr);
return new CosmWasmPriceFeedContract(chain, result.contractAddr);
}

getId(): string {
Expand All @@ -183,7 +183,7 @@ export class CosmWasmContract extends Contract {
return {
chain: this.chain.getId(),
address: this.address,
type: CosmWasmContract.type,
type: CosmWasmPriceFeedContract.type,
};
}

Expand Down
81 changes: 73 additions & 8 deletions contract_manager/src/contracts/evm.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Web3 from "web3";
import PythInterfaceAbi from "@pythnetwork/pyth-sdk-solidity/abis/IPyth.json";
import { Contract, PrivateKey } from "../base";
import EntropyAbi from "@pythnetwork/entropy-sdk-solidity/abis/IEntropy.json";
import { PriceFeedContract, PrivateKey, Storable } from "../base";
import { Chain, EvmChain } from "../chains";
import { DataSource } from "xc_admin_common";
import { WormholeContract } from "./wormhole";
Expand Down Expand Up @@ -281,8 +282,71 @@ export class WormholeEvmContract extends WormholeContract {
}
}

export class EvmContract extends Contract {
static type = "EvmContract";
interface EntropyProviderInfo {
feeInWei: string;
accruedFeesInWei: string;
originalCommitment: string;
originalCommitmentSequenceNumber: string;
commitmentMetadata: string;
uri: string;
endSequenceNumber: string;
sequenceNumber: string;
currentCommitment: string;
currentCommitmentSequenceNumber: string;
}

export class EvmEntropyContract extends Storable {
static type = "EvmEntropyContract";

constructor(public chain: EvmChain, public address: string) {
super();
}

getId(): string {
return `${this.chain.getId()}_${this.address}`;
}

getType(): string {
return EvmEntropyContract.type;
}

static fromJson(
chain: Chain,
parsed: { type: string; address: string }
): EvmEntropyContract {
if (parsed.type !== EvmEntropyContract.type)
throw new Error("Invalid type");
if (!(chain instanceof EvmChain))
throw new Error(`Wrong chain type ${chain}`);
return new EvmEntropyContract(chain, parsed.address);
}

toJson() {
return {
chain: this.chain.getId(),
address: this.address,
type: EvmPriceFeedContract.type,
};
}

getContract() {
const web3 = new Web3(this.chain.getRpcUrl());
return new web3.eth.Contract(EntropyAbi as any, this.address); // eslint-disable-line @typescript-eslint/no-explicit-any
}

async getDefaultProvider(): Promise<string> {
const contract = this.getContract();
return await contract.methods.getDefaultProvider().call();
}

async getProviderInfo(address: string): Promise<EntropyProviderInfo> {
const contract = this.getContract();
return await contract.methods.getProviderInfo(address).call();
}
}

export class EvmPriceFeedContract extends PriceFeedContract {
static type = "EvmPriceFeedContract";

constructor(public chain: EvmChain, public address: string) {
super();
Expand All @@ -291,19 +355,20 @@ export class EvmContract extends Contract {
static fromJson(
chain: Chain,
parsed: { type: string; address: string }
): EvmContract {
if (parsed.type !== EvmContract.type) throw new Error("Invalid type");
): EvmPriceFeedContract {
if (parsed.type !== EvmPriceFeedContract.type)
throw new Error("Invalid type");
if (!(chain instanceof EvmChain))
throw new Error(`Wrong chain type ${chain}`);
return new EvmContract(chain, parsed.address);
return new EvmPriceFeedContract(chain, parsed.address);
}

getId(): string {
return `${this.chain.getId()}_${this.address}`;
}

getType(): string {
return EvmContract.type;
return EvmPriceFeedContract.type;
}

async getVersion(): Promise<string> {
Expand Down Expand Up @@ -496,7 +561,7 @@ export class EvmContract extends Contract {
return {
chain: this.chain.getId(),
address: this.address,
type: EvmContract.type,
type: EvmPriceFeedContract.type,
};
}
}
Loading

0 comments on commit eef8468

Please sign in to comment.