Skip to content
This repository has been archived by the owner on Jan 24, 2024. It is now read-only.

feat(rocket-pool): Add Rocket Pool staked ETH #930

Merged
merged 1 commit into from
Jul 22, 2022
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[
{
"inputs": [{ "internalType": "address", "name": "_nodeAddress", "type": "address" }],
"name": "getNodeActiveMinipoolCount",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
}
]
64 changes: 64 additions & 0 deletions src/apps/rocket-pool/contracts/ethers/RocketMinipoolManager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type { BaseContract, BigNumber, BytesLike, CallOverrides, PopulatedTransaction, Signer, utils } from 'ethers';
import type { FunctionFragment, Result } from '@ethersproject/abi';
import type { Listener, Provider } from '@ethersproject/providers';
import type { TypedEventFilter, TypedEvent, TypedListener, OnEvent } from './common';

export interface RocketMinipoolManagerInterface extends utils.Interface {
functions: {
'getNodeActiveMinipoolCount(address)': FunctionFragment;
};

getFunction(nameOrSignatureOrTopic: 'getNodeActiveMinipoolCount'): FunctionFragment;

encodeFunctionData(functionFragment: 'getNodeActiveMinipoolCount', values: [string]): string;

decodeFunctionResult(functionFragment: 'getNodeActiveMinipoolCount', data: BytesLike): Result;

events: {};
}

export interface RocketMinipoolManager extends BaseContract {
connect(signerOrProvider: Signer | Provider | string): this;
attach(addressOrName: string): this;
deployed(): Promise<this>;

interface: RocketMinipoolManagerInterface;

queryFilter<TEvent extends TypedEvent>(
event: TypedEventFilter<TEvent>,
fromBlockOrBlockhash?: string | number | undefined,
toBlock?: string | number | undefined,
): Promise<Array<TEvent>>;

listeners<TEvent extends TypedEvent>(eventFilter?: TypedEventFilter<TEvent>): Array<TypedListener<TEvent>>;
listeners(eventName?: string): Array<Listener>;
removeAllListeners<TEvent extends TypedEvent>(eventFilter: TypedEventFilter<TEvent>): this;
removeAllListeners(eventName?: string): this;
off: OnEvent<this>;
on: OnEvent<this>;
once: OnEvent<this>;
removeListener: OnEvent<this>;

functions: {
getNodeActiveMinipoolCount(_nodeAddress: string, overrides?: CallOverrides): Promise<[BigNumber]>;
};

getNodeActiveMinipoolCount(_nodeAddress: string, overrides?: CallOverrides): Promise<BigNumber>;

callStatic: {
getNodeActiveMinipoolCount(_nodeAddress: string, overrides?: CallOverrides): Promise<BigNumber>;
};

filters: {};

estimateGas: {
getNodeActiveMinipoolCount(_nodeAddress: string, overrides?: CallOverrides): Promise<BigNumber>;
};

populateTransaction: {
getNodeActiveMinipoolCount(_nodeAddress: string, overrides?: CallOverrides): Promise<PopulatedTransaction>;
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */

import { Contract, Signer, utils } from 'ethers';
import type { Provider } from '@ethersproject/providers';
import type { RocketMinipoolManager, RocketMinipoolManagerInterface } from '../RocketMinipoolManager';

const _abi = [
{
inputs: [
{
internalType: 'address',
name: '_nodeAddress',
type: 'address',
},
],
name: 'getNodeActiveMinipoolCount',
outputs: [
{
internalType: 'uint256',
name: '',
type: 'uint256',
},
],
stateMutability: 'view',
type: 'function',
},
];

export class RocketMinipoolManager__factory {
static readonly abi = _abi;
static createInterface(): RocketMinipoolManagerInterface {
return new utils.Interface(_abi) as RocketMinipoolManagerInterface;
}
static connect(address: string, signerOrProvider: Signer | Provider): RocketMinipoolManager {
return new Contract(address, _abi, signerOrProvider) as RocketMinipoolManager;
}
}
1 change: 1 addition & 0 deletions src/apps/rocket-pool/contracts/ethers/factories/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
/* tslint:disable */
/* eslint-disable */
export { RocketDaoNodeTrusted__factory } from './RocketDaoNodeTrusted__factory';
export { RocketMinipoolManager__factory } from './RocketMinipoolManager__factory';
export { RocketNodeStaking__factory } from './RocketNodeStaking__factory';
2 changes: 2 additions & 0 deletions src/apps/rocket-pool/contracts/ethers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
/* tslint:disable */
/* eslint-disable */
export type { RocketDaoNodeTrusted } from './RocketDaoNodeTrusted';
export type { RocketMinipoolManager } from './RocketMinipoolManager';
export type { RocketNodeStaking } from './RocketNodeStaking';
export * as factories from './factories';
export { RocketDaoNodeTrusted__factory } from './factories/RocketDaoNodeTrusted__factory';
export { RocketMinipoolManager__factory } from './factories/RocketMinipoolManager__factory';
export { RocketNodeStaking__factory } from './factories/RocketNodeStaking__factory';
5 changes: 5 additions & 0 deletions src/apps/rocket-pool/contracts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ContractFactory } from '~contract/contracts';
import { Network } from '~types/network.interface';

import { RocketDaoNodeTrusted__factory } from './ethers';
import { RocketMinipoolManager__factory } from './ethers';
import { RocketNodeStaking__factory } from './ethers';

// eslint-disable-next-line
Expand All @@ -19,10 +20,14 @@ export class RocketPoolContractFactory extends ContractFactory {
rocketDaoNodeTrusted({ address, network }: ContractOpts) {
return RocketDaoNodeTrusted__factory.connect(address, this.appToolkit.getNetworkProvider(network));
}
rocketMinipoolManager({ address, network }: ContractOpts) {
return RocketMinipoolManager__factory.connect(address, this.appToolkit.getNetworkProvider(network));
}
rocketNodeStaking({ address, network }: ContractOpts) {
return RocketNodeStaking__factory.connect(address, this.appToolkit.getNetworkProvider(network));
}
}

export type { RocketDaoNodeTrusted } from './ethers';
export type { RocketMinipoolManager } from './ethers';
export type { RocketNodeStaking } from './ethers';
28 changes: 28 additions & 0 deletions src/apps/rocket-pool/ethereum/rocket-pool.balance-fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import { Network } from '~types/network.interface';

import { RocketPoolContractFactory } from '../contracts';
import { ROCKET_POOL_DEFINITION } from '../rocket-pool.definition';
import {
rocketMinipoolManagerAddress,
rocketNodeStakingAddress,
} from './rocket-pool.staking.contract-position-fetcher';

const network = Network.ETHEREUM_MAINNET;

Expand All @@ -21,11 +25,35 @@ export class EthereumRocketPoolBalanceFetcher implements BalanceFetcher {
) {}

async getStakedBalances(address: string) {
return [await this.getStakedEthBalance(address), await this.getStakedRplBalance(address)].flat();
}

async getStakedEthBalance(address: string) {
return this.appToolkit.helpers.contractPositionBalanceHelper.getContractPositionBalances({
address,
appId: ROCKET_POOL_DEFINITION.id,
groupId: ROCKET_POOL_DEFINITION.groups.staking.id,
network: Network.ETHEREUM_MAINNET,
filter: p => p.address == rocketMinipoolManagerAddress,
resolveBalances: async ({ address, contractPosition }) => {
const token = contractPosition.tokens.find(isSupplied)!;
const contract = this.rocketPoolContractFactory.rocketMinipoolManager(contractPosition);
const minipoolCount = (await contract.getNodeActiveMinipoolCount(address)).toNumber();
const minipoolDepositSize = 16 * 10 ** 18; // 16 ETH
const balanceRaw = minipoolCount * minipoolDepositSize;
const tokenBalance = drillBalance(token, balanceRaw.toString());
return [tokenBalance];
},
});
}

async getStakedRplBalance(address: string) {
return this.appToolkit.helpers.contractPositionBalanceHelper.getContractPositionBalances({
address,
appId: ROCKET_POOL_DEFINITION.id,
groupId: ROCKET_POOL_DEFINITION.groups.staking.id,
network: Network.ETHEREUM_MAINNET,
filter: p => p.address == rocketNodeStakingAddress,
resolveBalances: async ({ address, contractPosition }) => {
const token = contractPosition.tokens.find(isSupplied)!;
const contract = this.rocketPoolContractFactory.rocketNodeStaking(contractPosition);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Inject } from '@nestjs/common';

import { IAppToolkit, APP_TOOLKIT } from '~app-toolkit/app-toolkit.interface';
import { ZERO_ADDRESS } from '~app-toolkit/constants/address';
import { Register } from '~app-toolkit/decorators';
import { getImagesFromToken } from '~app-toolkit/helpers/presentation/image.present';
import { ContractType } from '~position/contract.interface';
Expand All @@ -11,21 +12,38 @@ import { Network } from '~types/network.interface';

import { ROCKET_POOL_DEFINITION } from '../rocket-pool.definition';

export const rocketNodeStakingAddress = '0x3019227b2b8493e45bf5d25302139c9a2713bf15';
export const rocketMinipoolManagerAddress = '0x6293B8abC1F36aFB22406Be5f96D893072A8cF3a';
export const rocketTokenRPLAddress = '0xd33526068d116ce69f19a9ee46f0bd304f21a51f';

const appId = ROCKET_POOL_DEFINITION.id;
const groupId = ROCKET_POOL_DEFINITION.groups.staking.id;
const network = Network.ETHEREUM_MAINNET;
const rocketNodeStakingAddress = '0x3019227b2b8493e45bf5d25302139c9a2713bf15';
const rocketTokenRPLAddress = '0xd33526068d116ce69f19a9ee46f0bd304f21a51f';

@Register.ContractPositionFetcher({ appId, groupId, network })
export class EthereumRocketPoolStakingContractPositionFetcher implements PositionFetcher<ContractPosition> {
constructor(@Inject(APP_TOOLKIT) private readonly appToolkit: IAppToolkit) {}

async getPositions() {
const baseTokens = await this.appToolkit.getBaseTokenPrices(network);
const eth = baseTokens.find(v => v.address === ZERO_ADDRESS)!;
const rpl = baseTokens.find(v => v.address === rocketTokenRPLAddress)!;

const position: ContractPosition = {
const ethposition: ContractPosition = {
type: ContractType.POSITION,
address: rocketMinipoolManagerAddress,
network,
appId,
groupId,
tokens: [supplied(eth)],
dataProps: {},
displayProps: {
label: `Staked ETH`,
images: getImagesFromToken(eth),
},
};

const rplposition: ContractPosition = {
type: ContractType.POSITION,
address: rocketNodeStakingAddress,
network,
Expand All @@ -39,6 +57,6 @@ export class EthereumRocketPoolStakingContractPositionFetcher implements Positio
},
};

return [position];
return [ethposition, rplposition];
}
}