Skip to content

Commit

Permalink
Merge pull request #92 from alpaca-finance/fix/rewarder-deposit-after…
Browse files Browse the repository at this point in the history
…-harvest

[main][fix] Fix wrong reward debt calculation
  • Loading branch information
alpanaca authored May 7, 2024
2 parents e68fa02 + 8655000 commit 4e5c875
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 38 deletions.
27 changes: 4 additions & 23 deletions contracts/8.19/xALPACAv2RevenueDistributor/xALPACAv2Rewarder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -96,32 +96,13 @@ contract xALPACAv2Rewarder is IxALPACAv2Rewarder, OwnableUpgradeable, Reentrancy
PoolInfo memory pool = _updatePool(_previousStakingReserve);
UserInfo storage user = userInfo[_user];

// calculate new staked amount
// example: if user deposit another 500 shares
// - user.amount = 100 => from previous deposit
// - _newAmount = 600 => updated staking amount from xALPACAv2RevenueDistributor
// _amount = _newAmount - user.amount = 600 - 100 = 500
uint256 _amount = _newAmount - user.amount;
uint256 _depositedAmount = _newAmount - _previousAmount;

user.amount = _newAmount;
// update user rewardDebt to separate new deposit share amount from pending reward in the pool
// example:
// - accRewardPerShare = 250
// - _receivedAmount = 100
// - pendingRewardReward = 25,000
// rewardDebt = previousRewardDebt + (_receivedAmount * accRewardPerShare)= 100 + (100 * 250) = 25,100
// This means newly deposit share does not eligible for 25,100 pending rewards

// handle if user already has deposited
// reward users supposed to get will be accounted here first
if (user.rewardDebt == 0 && _previousAmount > 0) {
user.rewardDebt =
user.rewardDebt -
(((_previousAmount * pool.accRewardPerShare) / ACC_REWARD_PRECISION)).toInt256();
}
user.rewardDebt = user.rewardDebt + ((_amount * pool.accRewardPerShare) / ACC_REWARD_PRECISION).toInt256();

emit LogOnDeposit(_user, _amount);
user.rewardDebt = user.rewardDebt + ((_depositedAmount * pool.accRewardPerShare) / ACC_REWARD_PRECISION).toInt256();

emit LogOnDeposit(_user, _depositedAmount);
}

/// @notice Hook Withdraw action from xALPACAv2RevenueDistributor.
Expand Down
59 changes: 59 additions & 0 deletions deploy/exec/xalpaca-v2-rewarder/config/find-pending-tokens.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { DeployFunction } from "hardhat-deploy/types";
import { ethers } from "hardhat";
import { XALPACAv2Rewarder__factory } from "../../../../typechain";
import { ConfigEntity } from "../../../entities";
import { getDeployer } from "../../../../utils/deployer-helper";

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
interface IRewarder {
NAME: string;
AMOUNT: string;
DECIMAL: number;
}
/*
░██╗░░░░░░░██╗░█████╗░██████╗░███╗░░██╗██╗███╗░░██╗░██████╗░
░██║░░██╗░░██║██╔══██╗██╔══██╗████╗░██║██║████╗░██║██╔════╝░
░╚██╗████╗██╔╝███████║██████╔╝██╔██╗██║██║██╔██╗██║██║░░██╗░
░░████╔═████║░██╔══██║██╔══██╗██║╚████║██║██║╚████║██║░░╚██╗
░░╚██╔╝░╚██╔╝░██║░░██║██║░░██║██║░╚███║██║██║░╚███║╚██████╔╝
░░░╚═╝░░░╚═╝░░╚═╝░░╚═╝╚═╝░░╚═╝╚═╝░░╚══╝╚═╝╚═╝░░╚══╝░╚═════╝░
Check all variables below before execute the deployment script
*/

const config = ConfigEntity.getConfig();

const REWARDER_NAME = "PYTH";
const accounts: string[] = [];

const rewarder = config.xALPACAv2Rewarders.find((rw) => rw.name === REWARDER_NAME);
if (!rewarder) {
console.log(`>> ${REWARDER_NAME} Rewarder not found`);
return;
}

const rewarderContract = XALPACAv2Rewarder__factory.connect(rewarder.address, ethers.provider);

let counter: number = 0;
const badAccounts: string[] = [];

for (const account of accounts) {
await rewarderContract.pendingToken(account).catch((e) => {
console.log(">> Error:", account);
badAccounts.push(account);
});
counter++;
}

if (counter !== accounts.length) {
console.log(`>> Exited before checking all accounts. ${counter} of ${accounts.length} checked.`);
}

console.log(`>> ${REWARDER_NAME} Rewarder bad accounts: ${badAccounts.length}`);
console.log(badAccounts);

console.log(`✅ Done`);
};

export default func;
func.tags = ["FindPendingTokens"];
80 changes: 73 additions & 7 deletions deploy/exec/xalpaca-v2-rewarder/config/force-set-reward-debt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import { getDeployer } from "../../../../utils/deployer-helper";
import { BigNumber } from "ethers";

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
interface IUserInfo {
user: string;
rewardDebt: number;
}
/*
░██╗░░░░░░░██╗░█████╗░██████╗░███╗░░██╗██╗███╗░░██╗░██████╗░
░██║░░██╗░░██║██╔══██╗██╔══██╗████╗░██║██║████╗░██║██╔════╝░
Expand All @@ -17,9 +21,68 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
Check all variables below before execute the deployment script
*/
const REWARDER = "PYTH";

const user = "0xd09fA948296E54D1Ab73A0497C16403A08A84732";
const newRewardDebt = 524935147;
const USERLIST: Array<IUserInfo> = [
{
user: "0x1300dedfb2f9671b6435dd4cb7ac40a5a3be51ff",
rewardDebt: 154288683,
},
{
user: "0x04938ffb0c749a11fcda6d5138a95b1cd76791d0",
rewardDebt: 0,
},
{
user: "0xa25ad78e8bf1ff9e5872662934ec4984b92611ff",
rewardDebt: 929,
},
{
user: "0x08943873222ce63ec48f8907757928dcb06af388",
rewardDebt: 389259,
},
{
user: "0xc3fd2bcb524af31963b3e3bb670f28ba14718244",
rewardDebt: 4027249,
},
{
user: "0x8bc888a4738f1e4291e041cbb225156da8f42059",
rewardDebt: 1083460,
},
{
user: "0xc8d5aca8fd339846d98bd246aee47f767daa1075",
rewardDebt: 21643899,
},
{
user: "0x0567d99a4420b8da0fd91c5ecba78955c04974f0",
rewardDebt: 3094379,
},
{
user: "0x539ec9fe37320828cdf639c2de93cbf1d1e5d257",
rewardDebt: 2087504,
},
{
user: "0xc110c1cd06e00273a770ef1555d2a8497aadff41",
rewardDebt: 13441254,
},
{
user: "0x736b9564c98325df57e3251d405a883fa85918fd",
rewardDebt: 16235119,
},
{
user: "0x902736ba2f6558332efbadb4a731af786e55f4b9",
rewardDebt: 37602,
},
{
user: "0xcffb39005a8dab478ef4188ae1b912f6e28ee3d3",
rewardDebt: 15207029,
},
{
user: "0x8674b6f34aa08aa8fa3d09551688e8cec70540ae",
rewardDebt: 150005014,
},
{
user: "0xbe68b3a1b22e84a89a8b3d47bcec8fba3fe0cc75",
rewardDebt: 1023506,
},
];

const deployer = await getDeployer();
const config = ConfigEntity.getConfig();
Expand All @@ -30,12 +93,15 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
console.log(`>> ${REWARDER} Rewarder not found`);
return;
}
console.log(
`>> Setting ${newRewardDebt} as a new reward debt for ${user} at Rewarder ${rewarder.name} at ${rewarder.address}`
);

const rewarderAsDeployer = XALPACAv2Rewarder__factory.connect(rewarder.address, deployer);

await rewarderAsDeployer.forceSetUserRewardDebt(user, newRewardDebt);
for (const user of USERLIST) {
console.log(
`>> Setting ${user.rewardDebt} as a new reward debt for ${user.user} at Rewarder ${rewarder.name} at ${rewarder.address}`
);
await rewarderAsDeployer.forceSetUserRewardDebt(user.user, user.rewardDebt);
}
console.log(`✅ Done`);
};

Expand Down
16 changes: 8 additions & 8 deletions deploy/exec/xalpaca-v2-rewarder/upgrade/xalpaca-v2-rewarder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ async function main() {
console.log("✅ Done");
}

main()
.then(() => {
process.exit(0);
})
.catch((error) => {
console.error(error);
process.exit(1);
});
// main()
// .then(() => {
// process.exit(0);
// })
// .catch((error) => {
// console.error(error);
// process.exit(1);
// });
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
"deploy:mainnet:xalpaca-v2-rewarder:deploy": "hardhat --network mainnet deploy --no-compile --reset --tags DeployxALPACAv2Rewarder",
"deploy:mainnet:xalpaca-v2-rewarder:config:feed-rewarder": "hardhat --network mainnet deploy --no-compile --reset --tags FeedRewarder",
"deploy:mainnet:xalpaca-v2-rewarder:config:withdraw": "hardhat --network mainnet deploy --no-compile --reset --tags RewarderWithdraw",
"deploy:mainnet:xalpaca-v2-rewarder:config:find-pending-tokens": "hardhat --network mainnet deploy --no-compile --reset --tags FindPendingTokens",
"deploy:mainnet:xalpaca-v2-rewarder:config:force-set-reward-debt": "hardhat --network mainnet deploy --no-compile --reset --tags RewarderForceSetRewardDebt",
"deploy:mainnet:xalpaca-v2-rewarder:upgrade": "hardhat --network mainnet deploy --no-compile --reset --tags UpgradeXALPACAv2Rewarder",
"deploy:fantom_testnet:proxy-token:deploy:proxy-token": "hardhat --network fantom_testnet deploy --no-compile --reset --tags ProxyToken",
Expand Down

0 comments on commit 4e5c875

Please sign in to comment.