From 66f524201f724861dffe70d08e04932f676024c6 Mon Sep 17 00:00:00 2001 From: Bryan Date: Wed, 22 May 2024 11:26:58 -0500 Subject: [PATCH] check if decayed and only claim upto endTs (#649) * check if decayed and only claim upto endTs * decayedEpoch * Add smart contract changes for fix * Bump cargo version --------- Co-authored-by: Noah Prince --- Cargo.lock | 2 +- .../src/hooks/useClaimAllPositionsRewards.ts | 11 ++++++++++- .../src/hooks/useClaimPositionRewards.ts | 11 ++++++++++- programs/helium-sub-daos/Cargo.toml | 2 +- .../instructions/delegation/close_delegation_v0.rs | 9 ++++++++- 5 files changed, 30 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2a871bc3a..c2c986333 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1958,7 +1958,7 @@ dependencies = [ [[package]] name = "helium-sub-daos" -version = "0.1.5" +version = "0.1.6" dependencies = [ "anchor-lang", "anchor-spl", diff --git a/packages/voter-stake-registry-hooks/src/hooks/useClaimAllPositionsRewards.ts b/packages/voter-stake-registry-hooks/src/hooks/useClaimAllPositionsRewards.ts index a485a0b2c..d512abb9d 100644 --- a/packages/voter-stake-registry-hooks/src/hooks/useClaimAllPositionsRewards.ts +++ b/packages/voter-stake-registry-hooks/src/hooks/useClaimAllPositionsRewards.ts @@ -98,6 +98,11 @@ export const useClaimAllPositionsRewards = () => { }, {} as Record); for (const [idx, position] of positions.entries()) { + const { lockup } = position; + const lockupKind = Object.keys(lockup.kind)[0] as string; + const isConstant = lockupKind === "constant"; + const isDecayed = !isConstant && lockup.endTs.lte(new BN(unixNow)); + const decayedEpoch = lockup.endTs.div(new BN(EPOCH_LENGTH)); const delegatedPosition = delegatedPositions[idx]; bucketedEpochsByPosition[position.pubkey.toBase58()] = bucketedEpochsByPosition[position.pubkey.toBase58()] || []; @@ -105,7 +110,11 @@ export const useClaimAllPositionsRewards = () => { delegatedPosition.account; const epoch = lastClaimedEpoch.add(new BN(1)); const epochsToClaim = Array.from( - { length: currentEpoch.sub(epoch).toNumber() }, + { + length: !isDecayed + ? currentEpoch.sub(epoch).toNumber() + : decayedEpoch.sub(epoch).toNumber(), + }, (_v, k) => epoch.addn(k) ).filter( (epoch) => diff --git a/packages/voter-stake-registry-hooks/src/hooks/useClaimPositionRewards.ts b/packages/voter-stake-registry-hooks/src/hooks/useClaimPositionRewards.ts index 5fe5995b6..e4191a4c6 100644 --- a/packages/voter-stake-registry-hooks/src/hooks/useClaimPositionRewards.ts +++ b/packages/voter-stake-registry-hooks/src/hooks/useClaimPositionRewards.ts @@ -46,6 +46,11 @@ export const useClaimPositionRewards = () => { if (isInvalid || !hsdProgram) { throw new Error("Unable to Claim Rewards, Invalid params"); } else { + const { lockup } = position; + const lockupKind = Object.keys(lockup.kind)[0] as string; + const isConstant = lockupKind === "constant"; + const isDecayed = !isConstant && lockup.endTs.lte(new BN(unixNow)); + const decayedEpoch = lockup.endTs.div(new BN(EPOCH_LENGTH)); const currentEpoch = new BN(unixNow).div(new BN(EPOCH_LENGTH)); const delegatedPosKey = delegatedPositionKey(position.pubkey)[0]; const delegatedPosAcc = @@ -54,7 +59,11 @@ export const useClaimPositionRewards = () => { const { lastClaimedEpoch, claimedEpochsBitmap } = delegatedPosAcc; const epoch = lastClaimedEpoch.add(new BN(1)); const epochsToClaim = Array.from( - { length: currentEpoch.sub(epoch).toNumber() }, + { + length: !isDecayed + ? currentEpoch.sub(epoch).toNumber() + : decayedEpoch.sub(epoch).toNumber(), + }, (_v, k) => epoch.addn(k) ).filter( (epoch) => diff --git a/programs/helium-sub-daos/Cargo.toml b/programs/helium-sub-daos/Cargo.toml index 189817539..117e7d43f 100644 --- a/programs/helium-sub-daos/Cargo.toml +++ b/programs/helium-sub-daos/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "helium-sub-daos" -version = "0.1.5" +version = "0.1.6" description = "Created with Anchor" edition = "2021" diff --git a/programs/helium-sub-daos/src/instructions/delegation/close_delegation_v0.rs b/programs/helium-sub-daos/src/instructions/delegation/close_delegation_v0.rs index 8cc9a30d2..a5556a38d 100644 --- a/programs/helium-sub-daos/src/instructions/delegation/close_delegation_v0.rs +++ b/programs/helium-sub-daos/src/instructions/delegation/close_delegation_v0.rs @@ -116,9 +116,16 @@ pub fn handler(ctx: Context) -> Result<()> { msg!("Vehnt calculations: {:?}", vehnt_info); // don't allow unstake without claiming available rewards + // make sure to account for when the position ends // unless we're testing, in which case we don't care let curr_epoch = current_epoch(curr_ts); - assert!((ctx.accounts.delegated_position.last_claimed_epoch >= curr_epoch - 1) || TESTING); + let to_claim_to_epoch = + if position.lockup.end_ts < curr_ts && position.lockup.kind == LockupKind::Cliff { + current_epoch(position.lockup.end_ts) + } else { + curr_epoch - 1 + }; + assert!((ctx.accounts.delegated_position.last_claimed_epoch >= to_claim_to_epoch) || TESTING); let delegated_position = &mut ctx.accounts.delegated_position; let sub_dao = &mut ctx.accounts.sub_dao;