Skip to content

Commit f5d8fd9

Browse files
authored
Merge pull request #205 from layerx-labs/dev
BEPRO 2.22.3
2 parents df9563b + 228d7ef commit f5d8fd9

20 files changed

+1432
-848
lines changed

package-lock.json

Lines changed: 832 additions & 828 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/actions/get-bounty-closed-event.ts

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import db from "src/db";
22
import logger from "src/utils/logger-handler";
33
import {EventsProcessed, EventsQuery,} from "src/interfaces/block-chain-service";
4-
import {DB_BOUNTY_NOT_FOUND, NETWORK_NOT_FOUND} from "../utils/messages.const";
4+
import {DB_BOUNTY_ALREADY_CLOSED, DB_BOUNTY_NOT_FOUND, NETWORK_NOT_FOUND} from "../utils/messages.const";
55
import {updateCuratorProposalParams} from "src/modules/handle-curators";
66
import {updateLeaderboardBounties, updateLeaderboardNfts, updateLeaderboardProposals} from "src/modules/leaderboard";
77
import {DecodedLog} from "../interfaces/block-sniffer";
@@ -12,6 +12,7 @@ import {updateBountiesHeader} from "src/modules/handle-header-information";
1212
import {Push} from "../services/analytics/push";
1313
import {AnalyticEventName} from "../services/analytics/types/events";
1414
import updateSeoCardBounty from "src/modules/handle-seo-card";
15+
import { savePointEvent } from "../modules/points-system/save-point-event";
1516

1617
export const name = "getBountyClosedEvents";
1718
export const schedule = "*/12 * * * *";
@@ -44,6 +45,8 @@ export async function action(block: DecodedLog, query?: EventsQuery): Promise<Ev
4445
const eventsProcessed: EventsProcessed = {};
4546
const {returnValues: {id, proposalId}, connection, address, chainId} = block;
4647

48+
const transaction = await connection.eth.getTransaction(block.transactionHash);
49+
4750
const bounty = await getBountyFromChain(connection, address, id, name);
4851
if (!bounty)
4952
return eventsProcessed;
@@ -67,6 +70,11 @@ export async function action(block: DecodedLog, query?: EventsQuery): Promise<Ev
6770
return eventsProcessed;
6871
}
6972

73+
if (dbBounty.state === "closed") {
74+
logger.warn(DB_BOUNTY_ALREADY_CLOSED(name, bounty.cid, network.id))
75+
return eventsProcessed;
76+
}
77+
7078
const dbProposal = await db.merge_proposals.findOne({
7179
where: {
7280
issueId: dbBounty.id,
@@ -80,7 +88,12 @@ export async function action(block: DecodedLog, query?: EventsQuery): Promise<Ev
8088
return eventsProcessed;
8189
}
8290

83-
const deliverable = await db.deliverables.findOne({ where: { id: dbProposal.deliverableId }});
91+
const deliverable = await db.deliverables.findOne({
92+
where: { id: dbProposal.deliverableId },
93+
include: [
94+
{ association: "user" }
95+
]
96+
});
8497
if (!deliverable) {
8598
logger.debug(`mergeProposal() has no deliverable on database`);
8699
return eventsProcessed;
@@ -102,7 +115,19 @@ export async function action(block: DecodedLog, query?: EventsQuery): Promise<Ev
102115
updateLeaderboardProposals("accepted");
103116
updateBountiesHeader();
104117
updateSeoCardBounty(dbBounty.id, name);
105-
118+
savePointEvent("accepted_proposal", transaction.from, {
119+
taskId: dbBounty.id,
120+
proposalId: dbProposal.id,
121+
merger: transaction.from
122+
});
123+
savePointEvent("created_proposal", dbProposal.creator!, {
124+
taskId: dbBounty.id,
125+
proposalId: dbProposal.id,
126+
});
127+
savePointEvent("created_deliverable", deliverable.user.address!, {
128+
taskId: dbBounty.id,
129+
deliverableId: deliverable.id,
130+
});
106131

107132
eventsProcessed[network.name!] = {
108133
[dbBounty.id!.toString()]: {bounty: dbBounty, eventBlock: parseLogWithContext(block)}

src/actions/get-bounty-moved-to-open.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,20 @@ import {BOUNTY_STATE_CHANGED} from "../integrations/telegram/messages";
1010
import {Push} from "../services/analytics/push";
1111
import {AnalyticEventName} from "../services/analytics/types/events";
1212
import updateSeoCardBounty from "src/modules/handle-seo-card";
13+
import { getCoinPrice } from "../services/coingecko";
14+
import { savePointEvent } from "../modules/points-system/save-point-event";
15+
import { getOrUpdateLastTokenPrice } from "../modules/tokens";
1316

1417
export const name = "get-bounty-moved-to-open";
1518
export const schedule = "*/1 * * * *";
1619
export const description =
1720
"move to 'OPEN' all 'DRAFT' bounties that have Draft Time finished as set at the block chain";
1821
export const author = "clarkjoao";
1922

20-
const {NEXT_WALLET_PRIVATE_KEY: privateKey} = process.env;
23+
const {
24+
NEXT_WALLET_PRIVATE_KEY: privateKey,
25+
NEXT_PUBLIC_CURRENCY_MAIN: currency = "eur",
26+
} = process.env;
2127

2228
export async function action(query?: EventsQuery): Promise<EventsProcessed> {
2329
const eventsProcessed: EventsProcessed = {};
@@ -62,7 +68,7 @@ export async function action(query?: EventsQuery): Promise<EventsProcessed> {
6268
network_id,
6369
state: "draft"
6470
},
65-
include: [{association: "network"}]
71+
include: [{association: "network"}, {association: "user"}]
6672
});
6773

6874
logger.info(`${name} found ${bounties.length} draft bounties on ${networkAddress}`);
@@ -75,10 +81,17 @@ export async function action(query?: EventsQuery): Promise<EventsProcessed> {
7581

7682
dbBounty.state = "open";
7783
await dbBounty.save();
78-
sendMessageToTelegramChannels(BOUNTY_STATE_CHANGED(dbBounty.state, dbBounty));
84+
sendMessageToTelegramChannels(BOUNTY_STATE_CHANGED(dbBounty.state!, dbBounty));
7985

8086
updateSeoCardBounty(dbBounty.id, name);
8187

88+
const tokenPrice = await getOrUpdateLastTokenPrice(dbBounty.transactionalTokenId!, currency);
89+
90+
await savePointEvent( "created_task",
91+
dbBounty.user.address!,
92+
{ taskId: dbBounty.id, taskAmount: dbBounty.amount, tokenPrice, currency },
93+
(pointsPerAction, scalingFactor) => pointsPerAction * scalingFactor * +dbBounty.amount! * tokenPrice);
94+
8295
eventsProcessed[networkName!] = {
8396
...eventsProcessed[networkName!],
8497
[dbBounty.id!.toString()]: {bounty: dbBounty, eventBlock: null}

src/actions/get-network-registered-events.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {DecodedLog} from "../interfaces/block-sniffer";
88
import {Network_v2} from "@taikai/dappkit";
99
import {Push} from "../services/analytics/push";
1010
import {AnalyticEventName} from "../services/analytics/types/events";
11+
import { savePointEvent } from "../modules/points-system/save-point-event";
1112

1213
export const name = "getNetworkRegisteredEvents";
1314
export const schedule = "*/10 * * * *";
@@ -48,6 +49,8 @@ export async function action(block: DecodedLog<NetworkCreatedEvent['returnValues
4849

4950
await network.save();
5051

52+
savePointEvent("created_marketplace", creator, { networkId: network.id });
53+
5154
updateNumberOfNetworkHeader();
5255

5356
logger.warn(`${name} Registered ${createdNetworkAddress}`);

src/actions/get-oracles-transfer-events.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,16 @@ export async function action(block: DecodedLog<OraclesTransferEvent['returnValue
4848
curators.push(curator?.address)
4949
}
5050

51+
const currentCurators = await db.curators.findAll({
52+
where: {
53+
isCurrentlyCurator: true,
54+
networkId: dbNetwork.id
55+
}
56+
});
57+
58+
dbNetwork.councilMembers = currentCurators.map(({ address }) => address);
59+
await dbNetwork.save();
60+
5161
eventsProcessed[dbNetwork.name!] = curators
5262

5363
Push.event(AnalyticEventName.DELEGATE_UNDELEGATE, {
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { Op } from "sequelize";
2+
import db, { sequelizeConnection } from "src/db";
3+
import logger from "src/utils/logger-handler";
4+
5+
export const name = "CalculatePointsDaily";
6+
export const schedule = "0 0 * * *";
7+
export const description = "Calculate total points and update users' total points";
8+
export const author = "Vitor Hugo";
9+
10+
export async function action() {
11+
logger.info(`${name} start`);
12+
13+
const events = await db.points_events.findAll({
14+
where: {
15+
pointsCounted: false,
16+
},
17+
order: ["userId"],
18+
raw: true
19+
});
20+
21+
if (!events?.length) {
22+
logger.info(`${name} no uncounted events found`);
23+
return;
24+
}
25+
26+
const pointsByUser = {} as { [userId: string]: { total: number, eventsIds: number[] } };
27+
28+
for (const event of events) {
29+
if (!pointsByUser[event.userId])
30+
pointsByUser[event.userId] = { total: 0, eventsIds: [] };
31+
32+
pointsByUser[event.userId].total += event.pointsWon;
33+
pointsByUser[event.userId].eventsIds.push(event.id);
34+
}
35+
36+
const updateUserPoints = Object.entries(pointsByUser).map(([id, { total }]) => ({ id, total }));
37+
const parsedEventsIds = Object.values(pointsByUser).map(({ eventsIds }) => eventsIds).flat();
38+
39+
try {
40+
await Promise.all(updateUserPoints.map(item => db.users.update({
41+
totalPoints: item.total
42+
}, {
43+
where: {
44+
id: item.id
45+
}
46+
})));
47+
48+
await db.points_events.update({
49+
pointsCounted: true,
50+
}, {
51+
where: {
52+
id: {
53+
[Op.in]: parsedEventsIds
54+
}
55+
}
56+
});
57+
58+
59+
logger.info(`${name} updated user points`, updateUserPoints);
60+
} catch(error) {
61+
logger.error(`${name} failed to update user points`, updateUserPoints, error);
62+
}
63+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { Op } from "sequelize";
2+
3+
import db from "src/db";
4+
5+
import logger from "src/utils/logger-handler";
6+
import { getOrUpdateLastTokenPrice } from "src/modules/tokens";
7+
import { savePointEvent } from "../../modules/points-system/save-point-event";
8+
9+
export const name = "SaveDelegatedTokensEvents";
10+
export const schedule = "0 0 * * *";
11+
export const description = "Save delegated tokens events on database";
12+
export const author = "Vitor Hugo";
13+
14+
export async function action() {
15+
logger.info(`${name} start`);
16+
17+
const delegations = await db.delegations.findAll({
18+
include: [
19+
{
20+
association: "network",
21+
include: [
22+
{ association: "network_token_token" }
23+
]
24+
}
25+
],
26+
});
27+
28+
const totalConvertedByCurator = {};
29+
const tokensPrices = {};
30+
31+
for (const delegation of delegations) {
32+
const tokenPrice = await getOrUpdateLastTokenPrice(delegation.network.network_token_id!);
33+
const convertedAmount = +delegation.amount! * tokenPrice;
34+
tokensPrices[delegation.network.network_token_token.symbol] = tokenPrice;
35+
totalConvertedByCurator[delegation.from] = (totalConvertedByCurator[delegation.from] || 0) + convertedAmount;
36+
}
37+
38+
for (const address in totalConvertedByCurator) {
39+
await savePointEvent( "delegated",
40+
address,
41+
{
42+
tokensPrices,
43+
delegations: delegations
44+
.filter(c => c.from.toLowerCase() === address.toLowerCase())
45+
.map(({ from, to, amount, networkId }) => ({ from, to, amount, networkId }))
46+
},
47+
(pointsPerAction, scalingFActor) => pointsPerAction * scalingFActor * totalConvertedByCurator[address]);
48+
}
49+
50+
logger.info(`${name} finished`);
51+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { Op } from "sequelize";
2+
3+
import db from "src/db";
4+
5+
import logger from "src/utils/logger-handler";
6+
import { getOrUpdateLastTokenPrice } from "src/modules/tokens";
7+
import { savePointEvent } from "../../modules/points-system/save-point-event";
8+
9+
export const name = "SaveLockedTokensEvents";
10+
export const schedule = "0 0 * * *";
11+
export const description = "Save locked tokens events on database";
12+
export const author = "Vitor Hugo";
13+
14+
export async function action() {
15+
logger.info(`${name} start`);
16+
17+
const curators = await db.curators.findAll({
18+
where: {
19+
tokensLocked: {
20+
[Op.not]: "0"
21+
}
22+
},
23+
include: [
24+
{
25+
association: "network",
26+
include: [
27+
{ association: "network_token_token" }
28+
]
29+
}
30+
],
31+
});
32+
33+
const totalConvertedByCurator = {};
34+
const tokensPrices = {};
35+
36+
for (const curator of curators) {
37+
const tokenPrice = await getOrUpdateLastTokenPrice(curator.network.network_token_id!);
38+
const convertedAmount = +curator.tokensLocked! * tokenPrice;
39+
tokensPrices[curator.network.network_token_token.symbol] = tokenPrice;
40+
totalConvertedByCurator[curator.address] = (totalConvertedByCurator[curator.address] || 0) + convertedAmount;
41+
}
42+
43+
for (const address in totalConvertedByCurator) {
44+
await savePointEvent( "locked",
45+
address,
46+
{
47+
tokensPrices,
48+
curators: curators
49+
.filter(c => c.address.toLowerCase() === address.toLowerCase())
50+
.map(({ tokensLocked, networkId }) => ({ tokensLocked, networkId }))
51+
},
52+
(pointsPerAction, scalingFActor) => pointsPerAction * scalingFActor * totalConvertedByCurator[address]);
53+
}
54+
55+
logger.info(`${name} finished`);
56+
}

src/actions/update-network-parameters.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {EventsProcessed, EventsQuery,} from "src/interfaces/block-chain-service"
44
import {Network_v2, Web3Connection} from "@taikai/dappkit";
55
import {Op} from "sequelize";
66
import {getChainsRegistryAndNetworks} from "../utils/block-process";
7-
import { updateIsCurrentlyCurator } from "src/modules/handle-curators";
7+
import { handleCurators, updateIsCurrentlyCurator } from "src/modules/handle-curators";
88

99
export const name = "updateNetworkParameters";
1010
export const schedule = "0 0 * * *";
@@ -44,8 +44,10 @@ export async function action(query?: EventsQuery): Promise<EventsProcessed> {
4444
try {
4545
const networkContract = new Network_v2(web3Connection, network.networkAddress);
4646
await networkContract.start();
47+
const councilAmount = await networkContract.councilAmount();
48+
const needsToUpdateCurators = councilAmount !== network.councilAmount;
4749

48-
network.councilAmount = await networkContract.councilAmount();
50+
network.councilAmount = councilAmount;
4951
network.disputableTime = (await networkContract.disputableTime()) / 1000;
5052
network.draftTime = (await networkContract.draftTime()) / 1000;
5153
network.oracleExchangeRate = await networkContract.oracleExchangeRate();
@@ -56,6 +58,23 @@ export async function action(query?: EventsQuery): Promise<EventsProcessed> {
5658

5759
await network.save();
5860

61+
if (needsToUpdateCurators) {
62+
await Promise.all(network.curators.map(async (curator) => {
63+
const actorVotesResume = await networkContract.getOraclesResume(curator.address);
64+
await handleCurators(curator.address, actorVotesResume, councilAmount, network.id);
65+
}));
66+
67+
const currentCurators = await db.curators.findAll({
68+
where: {
69+
isCurrentlyCurator: true,
70+
networkId: network.id
71+
}
72+
});
73+
74+
network.councilMembers = currentCurators.map(({ address }) => address);
75+
await network.save();
76+
}
77+
5978
eventsProcessed[network.name!] = ["updated"];
6079

6180
logger.info(`${name} parameters saved ${network.name} ${network.networkAddress}`);

src/db/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,13 @@ if (NEXT_DB_SSL === "true")
3434
},
3535
};
3636

37-
const con = new Sequelize(
37+
export const sequelizeConnection = new Sequelize(
3838
options.database!,
3939
options.username!,
4040
options.password!,
4141
options
4242
);
4343

44-
const modules = initModels(con);
44+
const modules = initModels(sequelizeConnection);
4545

4646
export default modules;

0 commit comments

Comments
 (0)