Skip to content
Merged
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
7 changes: 6 additions & 1 deletion contracts/interfaces/IStakingPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -144,5 +144,10 @@ interface IStakingPool {

/* ========== EVENTS ========== */

event StakeDeposited(address indexed user, uint256 amount, uint256 trancheId, uint256 tokenId);
event StakeDeposited(address indexed user, uint256 amount, uint256 trancheId, uint256 tokenId);

event PoolPrivacyChanged(address indexed manager, bool isPrivate);

event PoolFeeChanged(address indexed manager, uint newFee);

}
4 changes: 4 additions & 0 deletions contracts/modules/staking/StakingPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -1480,10 +1480,14 @@ function setProducts(StakedProductParam[] memory params) external onlyManager {
// sstore
deposits[0][trancheId] = feeDeposit;
}

emit PoolFeeChanged(msg.sender, newFee);
}

function setPoolPrivacy(bool _isPrivatePool) external onlyManager {
isPrivatePool = _isPrivatePool;

emit PoolPrivacyChanged(msg.sender, _isPrivatePool);
}

/* utils */
Expand Down
2 changes: 2 additions & 0 deletions test/unit/StakingPool/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ describe('StakingPool unit tests', function () {
// require('./getPrices');
require('./constructor');
require('./initialize');
require('./setPoolFee');
require('./setPoolPrivacy');
require('./calculateNewRewardShares');
require('./setProducts');
require('./depositTo');
Expand Down
157 changes: 157 additions & 0 deletions test/unit/StakingPool/setPoolFee.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
const { parseEther } = require('ethers/lib/utils');
const { ethers, expect } = require('hardhat');
const { daysToSeconds } = require('../../../lib/helpers');
const { setEtherBalance, increaseTime } = require('../../utils/evm');
const { getTranches } = require('./helpers');

describe('setPoolFee', function () {
const product0 = {
productId: 0,
weight: 100,
initialPrice: '500',
targetPrice: '500',
};

const initializeParams = {
poolId: 0,
isPrivatePool: false,
initialPoolFee: 5, // 5%
maxPoolFee: 5, // 5%
productInitializationParams: [product0],
};

beforeEach(async function () {
const {
stakingPool,
cover,
accounts: { defaultSender: manager },
} = this;

const { poolId, initialPoolFee, maxPoolFee, productInitializationParams, isPrivatePool } = initializeParams;

const coverSigner = await ethers.getImpersonatedSigner(cover.address);
await setEtherBalance(coverSigner.address, ethers.utils.parseEther('1'));

await stakingPool
.connect(coverSigner)
.initialize(manager.address, isPrivatePool, initialPoolFee, maxPoolFee, productInitializationParams, poolId);
});

it('reverts if manager is not the caller', async function () {
const {
stakingPool,
accounts: {
defaultSender: manager,
nonMembers: [nonManager],
},
} = this;

await expect(stakingPool.connect(nonManager).setPoolFee(5)).to.be.revertedWith(
'StakingPool: Only pool manager can call this function',
);
await expect(stakingPool.connect(manager).setPoolFee(5)).to.not.be.reverted;
});

it('reverts if new fee exceeds max pool fee', async function () {
const {
stakingPool,
accounts: { defaultSender: manager },
} = this;

const { maxPoolFee } = initializeParams;

await expect(stakingPool.connect(manager).setPoolFee(maxPoolFee + 1)).to.be.revertedWith(
'StakingPool: new fee exceeds max fee',
);
await expect(stakingPool.connect(manager).setPoolFee(maxPoolFee)).to.not.be.reverted;
});

it('updates pool fee', async function () {
const {
stakingPool,
accounts: { defaultSender: manager },
} = this;

const { maxPoolFee } = initializeParams;

const newPoolFee = maxPoolFee - 2;
expect(await stakingPool.poolFee()).to.be.eq(maxPoolFee);
await stakingPool.connect(manager).setPoolFee(newPoolFee);
expect(await stakingPool.poolFee()).to.be.eq(newPoolFee);
});

it('updates pool manager rewards', async function () {
const {
stakingPool,
cover,
accounts: {
defaultSender: manager,
members: [user],
},
} = this;

const { firstActiveTrancheId } = await getTranches();
const amount = parseEther('100');
const tokenId = 0;
const managerDepositId = 0;
const { initialPoolFee } = initializeParams;
const newPoolFee = initialPoolFee - 2;

await stakingPool.connect(user).depositTo([
{
amount,
trancheId: firstActiveTrancheId,
tokenId,
destination: ethers.constants.AddressZero,
},
]);

// Generate rewards
const coverRequest = {
coverId: 0,
productId: 0,
amount: parseEther('100'),
period: daysToSeconds(30),
gracePeriod: daysToSeconds(30),
globalCapacityRatio: 20000,
capacityReductionRatio: 0,
rewardRatio: 10000,
};

const coverSigner = await ethers.getImpersonatedSigner(cover.address);
await stakingPool.connect(coverSigner).allocateStake(coverRequest);

await increaseTime(daysToSeconds(25));

const managerDepositBefore = await stakingPool.deposits(managerDepositId, firstActiveTrancheId);

await stakingPool.connect(manager).setPoolFee(newPoolFee);
const accNxmPerRewardsShareBefore = await stakingPool.accNxmPerRewardsShare();

const managerDepositAfter = await stakingPool.deposits(managerDepositId, firstActiveTrancheId);

const newLastAccNxmPerRewardShare = accNxmPerRewardsShareBefore.sub(managerDepositBefore.lastAccNxmPerRewardShare);
expect(managerDepositAfter.lastAccNxmPerRewardShare).to.equal(newLastAccNxmPerRewardShare);
expect(managerDepositAfter.pendingRewards).to.equal(
managerDepositAfter.lastAccNxmPerRewardShare.mul(managerDepositBefore.rewardsShares),
);
expect(managerDepositAfter.rewardsShares).to.equal(
managerDepositBefore.rewardsShares.mul(newPoolFee).div(initialPoolFee),
);
});

it('emits and PoolFeeChanged', async function () {
const {
stakingPool,
accounts: { defaultSender: manager },
} = this;

const { maxPoolFee } = initializeParams;

const newPoolFee = maxPoolFee - 1;

await expect(stakingPool.connect(manager).setPoolFee(newPoolFee))
.to.emit(stakingPool, 'PoolFeeChanged')
.withArgs(manager.address, newPoolFee);
});
});
76 changes: 76 additions & 0 deletions test/unit/StakingPool/setPoolPrivacy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
const { ethers, expect } = require('hardhat');
const { setEtherBalance } = require('../../utils/evm');

describe('setPoolPrivacy', function () {
const product0 = {
productId: 0,
weight: 100,
initialPrice: '500',
targetPrice: '500',
};

const initializeParams = {
poolId: 0,
isPrivatePool: false,
initialPoolFee: 5, // 5%
maxPoolFee: 5, // 5%
productInitializationParams: [product0],
};

beforeEach(async function () {
const {
stakingPool,
cover,
accounts: { defaultSender: manager },
} = this;

const { poolId, initialPoolFee, maxPoolFee, productInitializationParams, isPrivatePool } = initializeParams;

const coverSigner = await ethers.getImpersonatedSigner(cover.address);
await setEtherBalance(coverSigner.address, ethers.utils.parseEther('1'));

await stakingPool
.connect(coverSigner)
.initialize(manager.address, isPrivatePool, initialPoolFee, maxPoolFee, productInitializationParams, poolId);
});

it('reverts if manager is not the caller', async function () {
const {
stakingPool,
accounts: {
defaultSender: manager,
nonMembers: [nonManager],
},
} = this;

await expect(stakingPool.connect(nonManager).setPoolPrivacy(true)).to.be.revertedWith(
'StakingPool: Only pool manager can call this function',
);
await expect(stakingPool.connect(manager).setPoolPrivacy(true)).to.not.be.reverted;
});

it('updates isPrivatePool flag', async function () {
const {
stakingPool,
accounts: { defaultSender: manager },
} = this;

const isPrivateBefore = await stakingPool.isPrivatePool();
await stakingPool.connect(manager).setPoolPrivacy(true);
const isPrivateAfter = await stakingPool.isPrivatePool();

expect(isPrivateAfter).to.not.eq(isPrivateBefore);
expect(isPrivateAfter).to.be.eq(true);
});

it('emits an event PoolPrivacyChanged', async function () {
const {
stakingPool,
accounts: { defaultSender: manager },
} = this;

await expect(stakingPool.connect(manager).setPoolPrivacy(true))
.to.emit(stakingPool, 'PoolPrivacyChanged')
.withArgs(manager.address, true);
});
});