@mihalex/farms-sdk-tests
Version:
74 lines (61 loc) • 1.98 kB
text/typescript
import { RewardInfo } from "../rpc_client/types";
import { UserState } from "../rpc_client/accounts/UserState";
import { FarmState } from "../rpc_client/accounts/FarmState";
import Decimal from "decimal.js";
import { WAD } from "./utils";
export function calculatePendingRewards(
farmState: FarmState,
userState: UserState,
rewardIndex: number,
ts: Decimal,
): Decimal {
const newRewardPerToken = calculateRewardPerStake(farmState, ts, rewardIndex);
const newRewardTally = new Decimal(
userState.activeStakeScaled.toString(),
).mul(newRewardPerToken);
const newReward = newRewardTally.sub(
new Decimal(userState.rewardsTallyScaled[rewardIndex].toString()),
);
return new Decimal(
userState.rewardsIssuedUnclaimed[rewardIndex].toString(),
).add(newReward.div(WAD));
}
export function calculateCurrentRewardPerToken(
farm: FarmState,
rewardIndex: number,
currentTimeUnit: Decimal,
): number {
const rewardCurve = farm.rewardInfos[rewardIndex].rewardScheduleCurve;
let index = 0;
for (let i = 0; i < rewardCurve.points.length; i++) {
if (
new Decimal(rewardCurve.points[i].tsStart.toString()).lte(currentTimeUnit)
) {
index = i;
} else {
break;
}
}
return rewardCurve.points[index].rewardPerTimeUnit.toNumber();
}
function calculateRewardPerStake(
farmState: FarmState,
ts: Decimal,
rewardIndex: number,
): Decimal {
const rewardInfo = farmState.rewardInfos[rewardIndex];
const tsDiff = ts.sub(new Decimal(rewardInfo.lastIssuanceTs.toString()));
let rps = calculateCurrentRewardPerToken(farmState, rewardIndex, ts);
const newRewards = Decimal.min(
tsDiff.mul(new Decimal(rps)),
new Decimal(rewardInfo.rewardsAvailable.toString()),
);
const rewardPerToken = new Decimal(
rewardInfo.rewardPerShareScaled.toString(),
).add(
newRewards
.mul(WAD)
.div(new Decimal(farmState.totalActiveStakeScaled.toString())),
);
return rewardPerToken;
}