Skip to content

Commit

Permalink
Merge pull request #713 from helium/feat/HIP-124
Browse files Browse the repository at this point in the history
[HIP-124] Implement rewards and tracking for positions that vote
  • Loading branch information
ChewingGlass authored Oct 23, 2024
2 parents ee9ca2a + aa08460 commit b283161
Show file tree
Hide file tree
Showing 102 changed files with 6,692 additions and 325 deletions.
1 change: 1 addition & 0 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ jobs:
- tests/voter-stake-registry.ts
- tests/fanout.ts
- tests/sus.ts
- tests/position-voting-rewards.ts
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/build-anchor/
Expand Down
2 changes: 2 additions & 0 deletions Anchor.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ fanout = "fanqeMu3fw8R4LwKNbahPtYXJsyLL6NXyfe2BqzhfB6"
mobile_entity_manager = "memMa1HG4odAFmUbGWfPwS1WWfK95k99F2YTkGvyxZr"
hexboosting = "hexbnKYoA2GercNNhHUCCfrTRWrHjT6ujKPXTa5NPqJ"
no_emit = "noEmmgLmQdk6DLiPV8CSwQv3qQDyGEhz9m5A4zhtByv"
position_voting_rewards = "pvr1pJdeAcW6tzFyPRSmkL5Xwysi1Tq79f7KF2XB4zM"

[workspace]
members = [
Expand All @@ -34,6 +35,7 @@ members = [
"programs/mobile-entity-manager",
"programs/hexboosting",
"programs/no-emit",
"programs/position-voting-rewards",
]

[registry]
Expand Down
18 changes: 16 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions packages/anchor-resolvers/src/heliumCommonResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ export const heliumCommonResolver = resolveIndividual(async ({ path }) => {
return new PublicKey("Sysvar1nstructions1111111111111111111111111");
case "lazyDistributorProgram":
return new PublicKey("1azyuavdMyvsivtNxPoz6SucD18eDHeXzFCUPq5XU7w");
case "positionVotingRewardsProgram":
return new PublicKey("pvr1pJdeAcW6tzFyPRSmkL5Xwysi1Tq79f7KF2XB4zM");
case "positionVotingRewards":
return new PublicKey("pvr1pJdeAcW6tzFyPRSmkL5Xwysi1Tq79f7KF2XB4zM");
case "noEmitProgram":
return new PublicKey("noEmmgLmQdk6DLiPV8CSwQv3qQDyGEhz9m5A4zhtByv");
default:
Expand Down
1 change: 1 addition & 0 deletions packages/crons/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"@helium/nft-proxy-sdk": "^0.0.12",
"@helium/no-emit-sdk": "^0.9.7",
"@helium/organization-sdk": "^0.0.12",
"@helium/position-voting-rewards-sdk": "^0.9.7",
"@helium/price-oracle-sdk": "^0.9.7",
"@helium/proposal-sdk": "^0.0.12",
"@helium/rewards-oracle-sdk": "^0.9.7",
Expand Down
36 changes: 35 additions & 1 deletion packages/crons/src/end-epoch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ import {
truthy,
} from "@helium/spl-utils";
import { getAccount } from "@solana/spl-token";
import { ComputeBudgetProgram as CBP, Connection, Keypair, SYSVAR_CLOCK_PUBKEY } from "@solana/web3.js";
import { init as initPVR, vsrEpochInfoKey } from "@helium/position-voting-rewards-sdk";
import { ComputeBudgetProgram as CBP, Connection, Keypair, PublicKey, SYSVAR_CLOCK_PUBKEY } from "@solana/web3.js";
import BN from "bn.js";
import bs58 from "bs58";

Expand Down Expand Up @@ -63,6 +64,7 @@ async function getSolanaUnixTimestamp(connection: Connection): Promise<bigint> {
const errors: string[] = [];
const provider = anchor.getProvider() as anchor.AnchorProvider;
const heliumSubDaosProgram = await initDao(provider);
const pvrProgram = await initPVR(provider);
const hntMint = HNT_MINT;
const iotMint = IOT_MINT;
const unixNow = new Date().valueOf() / 1000;
Expand Down Expand Up @@ -173,6 +175,38 @@ async function getSolanaUnixTimestamp(connection: Connection): Promise<bigint> {
);
}
}

const hasVeTokenTracker = !subDao.account.vetokenTracker.equals(PublicKey.default);
if (hasVeTokenTracker) {
const [vsrEpoch] = vsrEpochInfoKey(subDao.account.vetokenTracker, targetTs);
const vsrEpochInfo =
await pvrProgram.account.vsrEpochInfoV0.fetchNullable(
vsrEpoch
);
if (!vsrEpochInfo || !vsrEpochInfo.rewardsIssuedAt) {
try {
await sendInstructionsWithPriorityFee(
provider,
[
await heliumSubDaosProgram.methods
.issueVotingRewardsV0({ epoch })
.accounts({
subDao: subDao.publicKey,
vsrEpochInfo: vsrEpoch,
})
.instruction(),
],
{
basePriorityFee: BASE_PRIORITY_FEE,
}
);
} catch (err: any) {
errors.push(
`Failed to issue voting rewards for ${subDao.account.dntMint.toBase58()}: ${err}`
);
}
}
}
}
}

Expand Down
3 changes: 3 additions & 0 deletions packages/crons/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
{
"path": "../no-emit-sdk"
},
{
"path": "../position-voting-rewards-sdk"
},
{
"path": "../helium-sub-daos-sdk"
},
Expand Down
19 changes: 19 additions & 0 deletions packages/crons/yarn.deploy.lock
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ __metadata:
"@helium/nft-proxy-sdk": ^0.0.12
"@helium/no-emit-sdk": ^0.9.7
"@helium/organization-sdk": ^0.0.12
"@helium/position-voting-rewards-sdk": ^0.9.7
"@helium/price-oracle-sdk": ^0.9.7
"@helium/proposal-sdk": ^0.0.12
"@helium/rewards-oracle-sdk": ^0.9.7
Expand Down Expand Up @@ -446,6 +447,24 @@ __metadata:
languageName: node
linkType: hard

"@helium/position-voting-rewards-sdk@^0.9.7":
version: 0.0.0-use.local
resolution: "@helium/position-voting-rewards-sdk@workspace:packages/position-voting-rewards-sdk"
dependencies:
"@coral-xyz/anchor": ^0.28.0
"@helium/anchor-resolvers": ^0.9.7
"@helium/idls": ^0.9.7
"@helium/spl-utils": ^0.9.7
"@solana/spl-token": ^0.3.8
bn.js: ^5.2.0
bs58: ^4.0.1
git-format-staged: ^2.1.3
ts-loader: ^9.2.3
ts-node: ^10.9.1
typescript: ^5.2.2
languageName: unknown
linkType: soft

"@helium/price-oracle-sdk@^0.9.7":
version: 0.0.0-use.local
resolution: "@helium/price-oracle-sdk@workspace:packages/price-oracle-sdk"
Expand Down
2 changes: 2 additions & 0 deletions packages/helium-admin-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
"@helium/lazy-distributor-sdk": "^0.9.7",
"@helium/mobile-entity-manager-sdk": "^0.9.7",
"@helium/nft-proxy-sdk": "^0.0.12",
"@helium/organization-sdk": "^0.0.13",
"@helium/position-voting-rewards-sdk": "^0.9.7",
"@helium/price-oracle-sdk": "^0.9.7",
"@helium/spl-utils": "^0.9.7",
"@helium/treasury-management-sdk": "^0.9.7",
Expand Down
1 change: 1 addition & 0 deletions packages/helium-admin-cli/src/create-dao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ export async function run(args: any = process.argv) {
await heliumVsrProgram.methods
.initializeRegistrarV0({
positionUpdateAuthority: (await daoKey(hntKeypair.publicKey))[0],
positionFreezeAuthorities: [],
})
.accounts({
realm,
Expand Down
3 changes: 3 additions & 0 deletions packages/helium-admin-cli/src/create-subdao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ export async function run(args: any = process.argv) {
await heliumVsrProgram.methods
.initializeRegistrarV0({
positionUpdateAuthority: null,
positionFreezeAuthorities: [],
})
.accounts({
realm,
Expand Down Expand Up @@ -512,6 +513,8 @@ export async function run(args: any = process.argv) {
instructions: [
await heliumSubDaosProgram.methods
.updateSubDaoV0({
vetokenTracker: null,
votingRewardsPercent: null,
authority,
emissionSchedule,
dcBurnAuthority: null,
Expand Down
58 changes: 46 additions & 12 deletions packages/helium-admin-cli/src/end-epoch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
daoEpochInfoKey,
daoKey,
EPOCH_LENGTH,
init as initDao
init as initDao,
} from "@helium/helium-sub-daos-sdk";
import * as anchor from "@coral-xyz/anchor";
import { ComputeBudgetProgram, PublicKey } from "@solana/web3.js";
Expand All @@ -12,6 +12,10 @@ import b58 from "bs58";
import os from "os";
import yargs from "yargs/yargs";
import { sendInstructionsWithPriorityFee } from "@helium/spl-utils";
import {
init as initPVR,
vsrEpochInfoKey,
} from "@helium/position-voting-rewards-sdk";

export async function run(args: any = process.argv) {
const yarg = yargs(args).options({
Expand Down Expand Up @@ -42,19 +46,24 @@ export async function run(args: any = process.argv) {

const provider = anchor.getProvider() as anchor.AnchorProvider;
const heliumSubDaosProgram = await initDao(provider);
const pvrProgram = await initPVR(provider);
const hntMint = new PublicKey(argv.hntMint!);
const dao = await daoKey(hntMint)[0];
const subdaos = await heliumSubDaosProgram.account.subDaoV0.all([{
memcmp: {
offset: 8,
bytes: b58.encode(dao.toBuffer()),
}
}]);
let targetTs = argv.from ? new BN(argv.from) : subdaos[0].account.vehntLastCalculatedTs;
const subdaos = await heliumSubDaosProgram.account.subDaoV0.all([
{
memcmp: {
offset: 8,
bytes: b58.encode(dao.toBuffer()),
},
},
]);
let targetTs = argv.from
? new BN(argv.from)
: subdaos[0].account.vehntLastCalculatedTs;

while (targetTs.toNumber() < new Date().valueOf() / 1000) {
const epoch = currentEpoch(targetTs);
console.log(epoch.toNumber(), targetTs.toNumber())
console.log(epoch.toNumber(), targetTs.toNumber());
const daoEpochInfo =
await heliumSubDaosProgram.account.daoEpochInfoV0.fetchNullable(
daoEpochInfoKey(dao, targetTs)[0]
Expand Down Expand Up @@ -99,10 +108,35 @@ export async function run(args: any = process.argv) {
}`
);
}
}


const hasVeTokenTracker = !subDao.account.vetokenTracker.equals(
PublicKey.default
);
if (hasVeTokenTracker) {
const [vsrEpoch] = vsrEpochInfoKey(
subDao.account.vetokenTracker,
targetTs
);
const vsrEpochInfo =
await pvrProgram.account.vsrEpochInfoV0.fetchNullable(vsrEpoch);
if (!vsrEpochInfo || !vsrEpochInfo.rewardsIssuedAt) {
try {
await sendInstructionsWithPriorityFee(provider, [
await heliumSubDaosProgram.methods
.issueVotingRewardsV0({ epoch })
.accounts({ subDao: subDao.publicKey, vsrEpochInfo: vsrEpoch })
.instruction(),
]);
} catch (err: any) {
console.log(
`Failed to issue voting rewards for ${subDao.account.dntMint.toBase58()}: ${err}`
);
}
}
}
}
}

try {
if (!daoEpochInfo?.doneIssuingHstPool) {
await sendInstructionsWithPriorityFee(provider, [
Expand All @@ -115,7 +149,7 @@ export async function run(args: any = process.argv) {
} catch (e: any) {
console.log(`Failed to issue hst pool: ${e.message}`);
}

targetTs = targetTs.add(new BN(EPOCH_LENGTH));
}
}
Loading

0 comments on commit b283161

Please sign in to comment.