Skip to content

Commit ed1d2ab

Browse files
committed
v2 updates
1 parent 7d04e4e commit ed1d2ab

File tree

11 files changed

+2788
-3192
lines changed

11 files changed

+2788
-3192
lines changed

artifacts/contracts/ftso/implementation/FtsoManager.sol/FtsoManager.json

Lines changed: 0 additions & 1723 deletions
This file was deleted.

artifacts/contracts/protocol/implementation/FlareSystemsManager.sol/FlareSystemsManager.json

Lines changed: 1991 additions & 0 deletions
Large diffs are not rendered by default.

artifacts/contracts/staking/implementation/AddressBinder.sol/AddressBinder.json

Lines changed: 2 additions & 2 deletions
Large diffs are not rendered by default.

artifacts/contracts/tokenPools/implementation/FtsoRewardManager.sol/FtsoRewardManager.json

Lines changed: 0 additions & 1425 deletions
This file was deleted.

deploys/flare.json

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,4 @@
11
[
2-
{
3-
"name": "FtsoRewardManager",
4-
"contractName": "FtsoRewardManager.sol",
5-
"address": "0x85627d71921AE25769f5370E482AdA5E1e418d37"
6-
},
7-
{
8-
"name": "FtsoManager",
9-
"contractName": "FtsoManager.sol",
10-
"address": "0x2E99a4543F9ea708Cf8CCaC447515e61706D9DE9"
11-
},
122
{
133
"name": "PChainStakeMirrorMultiSigVoting",
144
"contractName": "PChainStakeMirrorMultiSigVoting.sol",
@@ -23,5 +13,10 @@
2313
"name": "AddressBinder",
2414
"contractName": "AddressBinder.sol",
2515
"address": "0x57c5149c6cdC7bA379aFAe28e6497Ae26c252738"
16+
},
17+
{
18+
"name": "FlareSystemsManager",
19+
"contractName": "FlareSystemsManager.sol",
20+
"address": "0x89e50DC0380e597ecE79c8494bAAFD84537AD0D4"
2621
}
2722
]

src/scripts/sync-artifacts.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { refreshArtifacts } from '../utils/artifact-utils';
22

3-
const contractToSync = ['FtsoManager', 'FtsoRewardManager', 'PChainStakeMirrorMultiSigVoting', 'AddressBinder', 'ValidatorRewardManager'];
3+
const contractToSync = ['FlareSystemsManager', 'PChainStakeMirrorMultiSigVoting', 'AddressBinder', 'ValidatorRewardManager'];
44

55
refreshArtifacts(contractToSync)
66
.then(() => process.exit(0))

src/services/CalculatingRewardsService.ts

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
import { Factory, Inject, Singleton } from 'typescript-ioc';
22
import { AttLogger } from '../logger/logger';
3-
import { DelegationData, DelegatorData, ActiveNode, Entity, FtsoData, NodeData, PAddressData, RewardsData, UptimeVote, RewardingPeriodData, DataValidatorRewardManager } from '../utils/interfaces';
3+
import { DelegationData, DelegatorData, ActiveNode, Entity, FtsoData, NodeData, PAddressData, RewardsData, UptimeVote, RewardingPeriodData, DataValidatorRewardManager, ClaimType, IRewardClaimWithProof } from '../utils/interfaces';
44
import { nodeIdToBytes20, pAddressToBytes20, sleepms } from '../utils/utils';
55
import { ConfigurationService } from './ConfigurationService';
66
import { ContractService } from './ContractService';
77
import { LoggerService } from './LoggerService';
88
import * as fs from 'fs';
9-
import { parse } from 'json2csv';
109
import axios from 'axios';
11-
import { FtsoRewardManager } from '../../typechain-web3-v1/FtsoRewardManager';
1210
import { EventProcessorService } from './EventProcessorService';
1311
import { AddressBinder } from '../../typechain-web3-v1/AddressBinder';
1412
import { ValidatorRewardManager } from '../../typechain-web3-v1/ValidatorRewardManager';
15-
import { FtsoManager } from '../../typechain-web3-v1/FtsoManager';
13+
import { FlareSystemsManager } from '../../typechain-web3-v1/FlareSystemsManager';
1614
// import { parse } from 'csv-parse';
1715
const parseCsv = require('csv-parse/lib/sync');
1816
const VALIDATORS_API = 'validators/list';
@@ -45,8 +43,7 @@ export class CalculatingRewardsService {
4543
this.logger.info(`waiting for network connection...`);
4644

4745
// contracts
48-
let ftsoManager = await this.contractService.ftsoManager();
49-
let ftsoRewardManager = await this.contractService.ftsoRewardManager();
46+
const flareSystemsManager = await this.contractService.flareSystemsManager();
5047
let validatorRewardManager = await this.contractService.validatorRewardManager();
5148
let pChainStakeMirrorMultiSigVoting = await this.contractService.pChainStakeMirrorMultiSigVoting();
5249
let addressBinder = await this.contractService.addressBinder();
@@ -68,7 +65,7 @@ export class CalculatingRewardsService {
6865

6966
if (rewardEpoch === undefined) {
7067
await sleepms(1000 / rps);
71-
rewardEpoch = parseInt(await ftsoRewardManager.methods.getCurrentRewardEpoch().call()) - 1;
68+
rewardEpoch = parseInt(await flareSystemsManager.methods.getCurrentRewardEpoch().call()) - 1;
7269
}
7370

7471
const generatedFilesPath = `generated-files/reward-epoch-${rewardEpoch}`
@@ -77,24 +74,23 @@ export class CalculatingRewardsService {
7774
let rewardAmount: bigint;
7875

7976
await sleepms(1000 / rps);
80-
let nextRewardEpochData = await ftsoManager.methods.getRewardEpochData((rewardEpoch + 1).toString()).call();
81-
let ftsoVpBlock = parseInt(nextRewardEpochData[0]);
82-
let nextRewardEpochStartBlock = parseInt(nextRewardEpochData[1]);
83-
let nextRewardEpochStartTs = parseInt(nextRewardEpochData[2]); // rewardEpochEndTs
84-
let stakingVpBlock = nextRewardEpochStartBlock - 2 * (nextRewardEpochStartBlock - ftsoVpBlock);
77+
const nextRewardEpochData = await flareSystemsManager.methods.getRewardEpochStartInfo(rewardEpoch + 1).call();
78+
const nextRewardEpochStartBlock = parseInt(nextRewardEpochData[1]);
79+
const nextRewardEpochStartTs = parseInt(nextRewardEpochData[0]); // rewardEpochEndTs
80+
const stakingVpBlock = Number(await flareSystemsManager.methods.getVotePowerBlock(rewardEpoch + 1).call());
8581

8682
//// get list of nodes with sufficient uptime
8783
await this.contractService.resetUptimeArray();
8884
await this.eventProcessorService.processEvents(nextRewardEpochStartBlock, rps, batchSize, uptimeVotingPeriodLengthSeconds, nextRewardEpochStartTs, rewardEpoch);
89-
let uptimeVotingData = await this.contractService.getUptimeVotingData();
90-
let eligibleNodesUptime = await this.getUptimeEligibleNodes(uptimeVotingData, uptimeVotingThreshold);
85+
const uptimeVotingData = await this.contractService.getUptimeVotingData();
86+
const eligibleNodesUptime = await this.getUptimeEligibleNodes(uptimeVotingData, uptimeVotingThreshold);
9187

9288
// get active nodes at staking vote power block
93-
let activeNodes = await this.getActiveStakes(stakingVpBlock, apiPath, VALIDATORS_API) as NodeData[];
89+
const activeNodes = await this.getActiveStakes(stakingVpBlock, apiPath, VALIDATORS_API) as NodeData[];
9490
activeNodes.sort((a, b) => a.startTime - b.startTime || a.nodeID.toLowerCase().localeCompare(b.nodeID.toLowerCase()));
9591

9692
// get delegations active at staking vp block
97-
let delegations = await this.getActiveStakes(stakingVpBlock, apiPath, DELEGATORS_API) as DelegationData[];
93+
const delegations = await this.getActiveStakes(stakingVpBlock, apiPath, DELEGATORS_API) as DelegationData[];
9894
delegations.sort((a, b) => a.startTime - b.startTime || a.txID.toLowerCase().localeCompare(b.txID.toLowerCase()));
9995

10096
// total stake (self-bonds + delegations) of the network at staking VP block
@@ -106,8 +102,14 @@ export class CalculatingRewardsService {
106102

107103
//// for each node check if it is eligible for rewarding, get its delegations, decide to which entity it belongs and calculate boost, total stake amount, ...
108104
this.logger.info(`^Rprocessing nodes data started`);
105+
// get ftso v2 performance data
106+
let res = await axios.get(`https://raw.githubusercontent.com/flare-foundation/fsp-rewards/refs/heads/main/flare/${rewardEpoch}/reward-distribution-data.json`);
107+
let data = res.data.rewardClaims.filter(
108+
claimWithProof =>
109+
claimWithProof.body.claimType == ClaimType.WNAT
110+
);
109111
for (const activeNode of activeNodes) {
110-
let [eligible, ftsoAddress, nonEligibilityReason, ftsoName] = await this.isEligibleForReward(activeNode, eligibleNodesUptime, ftsoAddresses, ftsoRewardManager, rewardEpoch, ftsoPerformanceForRewardWei, rps);
112+
let [eligible, ftsoAddress, nonEligibilityReason, ftsoName] = await this.isEligibleForReward(activeNode, eligibleNodesUptime, ftsoAddresses, rewardEpoch, ftsoPerformanceForRewardWei, data);
111113

112114
// decide to which group node belongs
113115
let node = await this.nodeGroup(activeNode, ftsoAddress, boostingAddresses, pChainAddresses);
@@ -201,7 +203,7 @@ export class CalculatingRewardsService {
201203

202204
// reward amount available for distribution
203205
if (rewardAmountEpochWei === undefined) {
204-
rewardAmount = await this.getRewardAmount(validatorRewardManager, ftsoManager);
206+
rewardAmount = await this.getRewardAmount(validatorRewardManager, flareSystemsManager);
205207
} else {
206208
rewardAmount = BigInt(rewardAmountEpochWei);
207209
}
@@ -339,11 +341,11 @@ export class CalculatingRewardsService {
339341
}
340342

341343
// check if node is eligible (high enough ftso performance and uptime) for rewards
342-
public async isEligibleForReward(node: NodeData, eligibleNodesUptime: string[], ftsoAddresses: FtsoData[], ftsoRewardManager: FtsoRewardManager, epochNum: number, ftsoPerformanceForReward: string, rps: number): Promise<[boolean, string, string, string]> {
344+
public async isEligibleForReward(node: NodeData, eligibleNodesUptime: string[], ftsoAddresses: FtsoData[], epochNum: number, ftsoPerformanceForReward: string, ftsoPerformanceData: any): Promise<[boolean, string, string, string]> {
343345

344346
let nonEligibilityReason: string;
345347
// find node's entity/ftso address
346-
let ftsoObj = ftsoAddresses.find(obj => {
348+
const ftsoObj = ftsoAddresses.find(obj => {
347349
return obj.nodeId == node.nodeID;
348350
})
349351
if (ftsoObj === undefined || ftsoObj.firstEpoch > epochNum) {
@@ -354,14 +356,18 @@ export class CalculatingRewardsService {
354356
// uptime
355357
if (!eligibleNodesUptime.includes(nodeIdToBytes20(node.nodeID))) {
356358
nonEligibilityReason = "not high enough uptime";
359+
this.logger.info(`${node.nodeID}: not high enough uptime`);
357360
return [false, ftsoObj.ftsoAddress, nonEligibilityReason, ftsoObj.ftsoName];
358361
}
359362

360363
// ftso rewards
361-
await sleepms(1000 / rps);
362-
let ftsoPerformance = await ftsoRewardManager.methods.getDataProviderPerformanceInfo(epochNum.toString(), ftsoObj.ftsoAddress).call();
363-
if (BigInt(ftsoPerformance[0]) <= BigInt(ftsoPerformanceForReward)) {
364+
const rewardClaim: IRewardClaimWithProof = ftsoPerformanceData.find((claimWithProof: IRewardClaimWithProof) => {
365+
return claimWithProof.body.beneficiary.toLowerCase() == ftsoObj.ftsoAddress.toLowerCase();
366+
});
367+
// data provider has reward amount 0 or lower than ftsoPerformanceForReward
368+
if (rewardClaim == undefined || BigInt(rewardClaim.body.amount) <= BigInt(ftsoPerformanceForReward)) {
364369
nonEligibilityReason = "not high enough FTSO performance";
370+
this.logger.info(`${node.nodeID}: not high enough FTSO performance`);
365371
return [false, ftsoObj.ftsoAddress, nonEligibilityReason, ftsoObj.ftsoName];
366372
}
367373
return [true, ftsoObj.ftsoAddress, nonEligibilityReason, ftsoObj.ftsoName];
@@ -420,9 +426,9 @@ export class CalculatingRewardsService {
420426
return [activeNodes, totalCappedWeightEligible, entities];
421427
}
422428

423-
public async getRewardAmount(validatorRewardManager: ValidatorRewardManager, ftsoManager: FtsoManager): Promise<bigint> {
429+
public async getRewardAmount(validatorRewardManager: ValidatorRewardManager, flareSystemsManager: FlareSystemsManager): Promise<bigint> {
424430
let totals = await validatorRewardManager.methods.getTotals().call();
425-
let epochDurationSeconds = await ftsoManager.methods.rewardEpochDurationSeconds().call();
431+
let epochDurationSeconds = await flareSystemsManager.methods.rewardEpochDurationSeconds().call();
426432
return BigInt(totals[5]) * BigInt(epochDurationSeconds) / BigInt(DAY_SECONDS);
427433
}
428434

src/services/ContractService.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { FtsoRewardManager } from '../../typechain-web3-v1/FtsoRewardManager';
1111
import { PChainStakeMirrorMultiSigVoting } from '../../typechain-web3-v1/PChainStakeMirrorMultiSigVoting';
1212
import { AddressBinder } from '../../typechain-web3-v1/AddressBinder';
1313
import { ValidatorRewardManager } from '../../typechain-web3-v1/ValidatorRewardManager';
14+
import { FlareSystemsManager } from '../../typechain-web3-v1/FlareSystemsManager';
1415

1516
@Singleton
1617
@Factory(() => new ContractService())
@@ -92,12 +93,8 @@ export class ContractService {
9293
}
9394

9495
/// Specific contracts - add them manually here
95-
public async ftsoManager(): Promise<FtsoManager> {
96-
return (await this.getContract('FtsoManager')) as FtsoManager;
97-
}
98-
99-
public async ftsoRewardManager(): Promise<FtsoRewardManager> {
100-
return (await this.getContract('FtsoRewardManager')) as FtsoRewardManager;
96+
public async flareSystemsManager(): Promise<FlareSystemsManager> {
97+
return (await this.getContract('FlareSystemsManager')) as FlareSystemsManager;
10198
}
10299

103100
public async validatorRewardManager(): Promise<ValidatorRewardManager> {

src/utils/interfaces.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,24 @@ export interface UptimeVote {
118118
nodeIds: string[];
119119
}
120120

121+
export enum ClaimType {
122+
DIRECT,
123+
FEE,
124+
WNAT,
125+
MIRROR,
126+
CCHAIN,
127+
}
128+
export interface IRewardClaim {
129+
beneficiary: string;
130+
amount: bigint;
131+
claimType: ClaimType;
132+
rewardEpochId: number;
133+
}
134+
export interface IRewardClaimWithProof {
135+
merkleProof: string[];
136+
body: IRewardClaim;
137+
}
138+
121139
// Config file exports
122140
export interface INetworkConfigJson {
123141
NETWORK: string;

typechain-web3-v1/AddressBinder.d.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,15 @@ export interface AddressBinder extends BaseContract {
4949
_pAddress: string | number[],
5050
_cAddress: string
5151
): NonPayableTransactionObject<void>;
52+
53+
registerPublicKey(
54+
_publicKey: string | number[]
55+
): NonPayableTransactionObject<{
56+
_pAddress: string;
57+
_cAddress: string;
58+
0: string;
59+
1: string;
60+
}>;
5261
};
5362
events: {
5463
AddressesRegistered(cb?: Callback<AddressesRegistered>): EventEmitter;

0 commit comments

Comments
 (0)