Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[HIP-138] (needs approval) Implement HIP-138 by adding update escrow to subdao and HST redirect #733

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Open
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
3 changes: 3 additions & 0 deletions Anchor.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ url = "https://api.mainnet-beta.solana.com"
[[test.validator.clone]]
address = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s" # token-metadata

[[test.validator.clone]]
address = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" # associated-token-program

[[test.validator.clone]]
address = "BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY" # bubblegum

Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

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

133 changes: 60 additions & 73 deletions packages/crons/src/end-epoch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,25 +223,6 @@ async function getSolanaUnixTimestamp(connection: Connection): Promise<bigint> {
}
}

if (!daoEpochInfo?.doneIssuingHstPool) {
try {
await sendInstructionsWithPriorityFee(
provider,
[
await heliumSubDaosProgram.methods
.issueHstPoolV0({ epoch })
.accounts({ dao })
.instruction(),
],
{
basePriorityFee: BASE_PRIORITY_FEE,
}
);
} catch (err: any) {
errors.push(`Failed to issue hst pool: ${err}`);
}
}

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

Expand Down Expand Up @@ -289,72 +270,78 @@ async function getSolanaUnixTimestamp(connection: Connection): Promise<bigint> {
const hemProgram = await initHem(provider);
const lazyProgram = await initLazy(provider);
const rewardsOracleProgram = await initRewards(provider);
const [lazyDistributor] = lazyDistributorKey(iotMint);
const [keyToAsset] = keyToAssetKey(dao, IOT_OPERATIONS_FUND, "utf8");
const assetId = (await hemProgram.account.keyToAssetV0.fetch(keyToAsset))
.asset;

const [recipient] = recipientKey(lazyDistributor, assetId);
if (!(await provider.connection.getAccountInfo(recipient))) {
const method = lazyProgram.methods.initializeRecipientV0().accounts({
lazyDistributor,
mint: assetId,
});

await sendInstructionsWithPriorityFee(provider, [await method.instruction()], {
basePriorityFee: BASE_PRIORITY_FEE
});
}
for (const token of [IOT_MINT, HNT_MINT]) {
const [lazyDistributor] = lazyDistributorKey(token);
const [keyToAsset] = keyToAssetKey(dao, IOT_OPERATIONS_FUND, "utf8");
const assetId = (await hemProgram.account.keyToAssetV0.fetch(keyToAsset))
.asset;

const [recipient] = recipientKey(lazyDistributor, assetId);
if (!(await provider.connection.getAccountInfo(recipient))) {
const method = lazyProgram.methods.initializeRecipientV0().accounts({
lazyDistributor,
mint: assetId,
});

await sendInstructionsWithPriorityFee(
provider,
[await method.instruction()],
{
basePriorityFee: BASE_PRIORITY_FEE,
}
);
}

const rewards = await client.getCurrentRewards(
lazyProgram,
lazyDistributor,
assetId
);
const rewards = await client.getCurrentRewards(
lazyProgram,
lazyDistributor,
assetId
);

const pending = await client.getPendingRewards(
lazyProgram,
lazyDistributor,
daoKey(HNT_MINT)[0],
[IOT_OPERATIONS_FUND],
"utf8"
);
const pending = await client.getPendingRewards(
lazyProgram,
lazyDistributor,
daoKey(HNT_MINT)[0],
[IOT_OPERATIONS_FUND],
"utf8"
);

// Avoid claiming too much and tripping the breaker
if (new BN(pending[IOT_OPERATIONS_FUND]).gt(MAX_CLAIM_AMOUNT)) {
rewards[0].currentRewards = new BN(rewards[0].currentRewards)
.sub(new BN(pending[IOT_OPERATIONS_FUND]))
.add(MAX_CLAIM_AMOUNT)
.toString();
}
// Avoid claiming too much and tripping the breaker
if (new BN(pending[IOT_OPERATIONS_FUND]).gt(MAX_CLAIM_AMOUNT)) {
rewards[0].currentRewards = new BN(rewards[0].currentRewards)
.sub(new BN(pending[IOT_OPERATIONS_FUND]))
.add(MAX_CLAIM_AMOUNT)
.toString();
}

const tx = await client.formTransaction({
program: lazyProgram,
rewardsOracleProgram: rewardsOracleProgram,
provider,
rewards,
asset: assetId,
lazyDistributor,
});
const tx = await client.formTransaction({
program: lazyProgram,
rewardsOracleProgram: rewardsOracleProgram,
provider,
rewards,
asset: assetId,
lazyDistributor,
});

const signed = await provider.wallet.signTransaction(tx);
const signed = await provider.wallet.signTransaction(tx);

try {
await sendAndConfirmWithRetry(
provider.connection,
Buffer.from(signed.serialize()),
{ skipPreflight: true },
"confirmed"
);
} catch (err: any) {
errors.push(`Failed to distribute iot op funds: ${err}`);
try {
await sendAndConfirmWithRetry(
provider.connection,
Buffer.from(signed.serialize()),
{ skipPreflight: true },
"confirmed"
);
} catch (err: any) {
errors.push(`Failed to distribute iot op funds: ${err}`);
}
}

// Only do this if that feature has been deployed
if (hemProgram.methods.issueNotEmittedEntityV0) {
console.log("Issuing no_emit");
const noEmitProgram = await initBurn(provider);
const tokens = [MOBILE_MINT, IOT_MINT];
const tokens = [MOBILE_MINT, IOT_MINT, HNT_MINT];
for (const token of tokens) {
const [lazyDistributor] = lazyDistributorKey(token);
const notEmittedEntityKta = keyToAssetKey(dao, NOT_EMITTED, "utf-8")[0];
Expand Down
13 changes: 10 additions & 3 deletions packages/distributor-oracle/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,18 +277,22 @@ export async function formBulkTransactions({
assetEndpoint || provider.connection.rpcEndpoint,
assets
);
const willPay = (await axios.get(
`${lazyDistributorAcc.oracles[0].url}/will-pay-recipient`
)).data.willPay;
let ixsPerAsset = await Promise.all(
recipientAccs.map(async (recipientAcc, idx) => {
if (!recipientAcc) {
return [
await (
await(
await initializeCompressionRecipient({
program: lazyDistributorProgram,
assetId: assets![idx],
lazyDistributor,
assetEndpoint,
owner: wallet,
payer,
// Temporarily set oracle as the payer to subsidize new HNT wallets.
payer: willPay ? lazyDistributorAcc.oracles[0].oracle : payer,
getAssetFn: () => Promise.resolve(compressionAssetAccs![idx]), // cache result so we don't hit again
getAssetProofFn: assetProofsById
? () =>
Expand Down Expand Up @@ -522,6 +526,9 @@ export async function formTransaction({
const recipientAcc =
await lazyDistributorProgram.account.recipientV0.fetchNullable(recipient);
if (!recipientAcc) {
const willPay = (
await axios.get(`${lazyDistributorAcc.oracles[0].url}/will-pay-recipient`)
).data.willPay;
let initRecipientIx;
if (assetAcc.compression.compressed) {
initRecipientIx = await (
Expand All @@ -531,7 +538,7 @@ export async function formTransaction({
lazyDistributor,
assetEndpoint,
owner: wallet,
payer,
payer: willPay ? lazyDistributorAcc.oracles[0].oracle : payer,
getAssetFn: () => Promise.resolve(assetAcc), // cache result so we don't hit again
getAssetProofFn,
})
Expand Down
24 changes: 24 additions & 0 deletions packages/distributor-oracle/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,17 @@ export class OracleServer {
private addRoutes() {
this.app.get("/active-devices", this.getActiveDevicesHandler.bind(this));
this.app.post("/bulk-rewards", this.getAllRewardsHandler.bind(this));
this.app.get(
"/will-pay-recipient",
(
_req: FastifyRequest<{ Body: { entityKeys: string[] } }>,
res: FastifyReply
) => {
res.send({
willPay: process.env.WILL_PAY_RECIPIENT === "true",
});
}
);
this.app.get<{
Querystring: {
assetId?: string;
Expand Down Expand Up @@ -361,6 +372,10 @@ export class OracleServer {
initCompressionRecipientTx.accounts.findIndex(
(x) => x.name === "lazyDistributor"
)!;
const payerIdxInitCompressionRecipient =
initCompressionRecipientTx.accounts.findIndex(
(x) => x.name === "payer"
)!;
const mintIdx = initRecipientTx.accounts.findIndex(
(x) => x.name === "mint"
)!;
Expand Down Expand Up @@ -443,6 +458,15 @@ export class OracleServer {
allAccs[ix.accountKeyIndexes[lazyDistributorIdxInitCompressionRecipient]].toBase58();
const merkleTree =
allAccs[ix.accountKeyIndexes[merkleTreeIdxInitCompressionRecipient]];
const payer =
allAccs[ix.accountKeyIndexes[payerIdxInitCompressionRecipient]].toBase58();

if (process.env.WILL_PAY_RECIPIENT !== "true" && payer === this.oracle.publicKey.toBase58()) {
return {
success: false,
message: "Cannot set this oracle as the payer",
};
}

const index = (decoded.data as any).args.index;
recipientToLazyDistToMint[recipient][lazyDist] = await getLeafAssetId(
Expand Down
12 changes: 4 additions & 8 deletions packages/helium-admin-cli/emissions/hst.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
[
{
"startTime": "2023-04-18T00:00:00Z",
"percent": 32
},
{
"startTime": "2023-08-01T00:00:00Z",
"percent": 31
},
{
"startTime": "2024-08-01T00:00:01Z",
"percent": 30
},
{
"startTime": "2025-08-01T00:00:01Z",
"percent": 0
}
]
1 change: 0 additions & 1 deletion packages/helium-admin-cli/src/create-subdao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,6 @@ export async function run(args: any = process.argv) {
.accounts({
dao,
dntMint: subdaoKeypair.publicKey,
rewardsEscrow,
hntMint: new PublicKey(argv.hntPubkey!),
payer,
dntMintAuthority: daoAcc.authority,
Expand Down
13 changes: 0 additions & 13 deletions packages/helium-admin-cli/src/end-epoch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,19 +137,6 @@ export async function run(args: any = process.argv) {
}
}

try {
if (!daoEpochInfo?.doneIssuingHstPool) {
await sendInstructionsWithPriorityFee(provider, [
await heliumSubDaosProgram.methods
.issueHstPoolV0({ epoch })
.accounts({ dao })
.instruction(),
]);
}
} catch (e: any) {
console.log(`Failed to issue hst pool: ${e.message}`);
}

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