Skip to content

Commit

Permalink
Merge pull request #22 from iotexproject/claim-cap
Browse files Browse the repository at this point in the history
add project cap for period
  • Loading branch information
ququzone authored Sep 19, 2024
2 parents aff3b4b + 0573bf5 commit c3d37a6
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 2 deletions.
38 changes: 36 additions & 2 deletions contracts/PeriodClaimVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ contract PeriodClaimVault is OwnableUpgradeable {
event ChangeRewardPerDevice(uint256 projectId, uint256 rewardPerDevice);
event ChangeRecipient(address indexed admin, uint256 projectId, address recipient);
event SetInvalidDevice(uint256 projectId, uint256 amount);
event SetProjectCap(uint256 projectId, uint256 cap);

IioIDStore public ioIDStore;
uint256 public period;
Expand All @@ -27,6 +28,7 @@ contract PeriodClaimVault is OwnableUpgradeable {
mapping(uint256 => address) public projectRecipient;
mapping(uint256 => uint256) public projectInvalidDevice;
mapping(uint256 => uint256) public lastClaimedTimestamp;
mapping(uint256 => uint256) public projectCap;

function initialize(address _ioIDStore) public initializer {
require(_ioIDStore != address(0), "zero address");
Expand Down Expand Up @@ -73,9 +75,15 @@ contract PeriodClaimVault is OwnableUpgradeable {
require(_lastClaimedTimestamp != 0, "invalid project");
require(_lastClaimedTimestamp + period <= block.timestamp, "claim too short");
uint256 _claimablePeriods = (block.timestamp - _lastClaimedTimestamp) / period;
uint256 _rewards = _claimablePeriods *
rewardPerDevice[_projectId] *

uint256 _periodRewards = rewardPerDevice[_projectId] *
(ioIDStore.projectActivedAmount(_projectId) - projectInvalidDevice[_projectId]);
uint256 _cap = projectCap[_projectId];
if (_cap != 0 && _periodRewards > _cap) {
_periodRewards = _cap;
}

uint256 _rewards = _claimablePeriods * _periodRewards;
require(address(this).balance >= _rewards, "insufficient fund");
lastClaimedTimestamp[_projectId] += (_claimablePeriods * period);
address _recipient = projectRecipient[_projectId];
Expand All @@ -101,6 +109,32 @@ contract PeriodClaimVault is OwnableUpgradeable {
emit ChangeRewardPerDevice(_projectId, _rewardPerDevice);
}

function setProjectCap(uint256 _projectId, uint256 _cap) external onlyOwner {
require(_cap > 0, "invalid cap");
require(projectRecipient[_projectId] != address(0), "invalid project");

projectCap[_projectId] = _cap;
emit SetProjectCap(_projectId, _cap);
}

function claimableRewards(uint256 _projectId) external view returns (uint256) {
uint256 _lastClaimedTimestamp = lastClaimedTimestamp[_projectId];
require(_lastClaimedTimestamp != 0, "invalid project");
uint256 _claimablePeriods = (block.timestamp - _lastClaimedTimestamp) / period;
if (_claimablePeriods == 0) {
return 0;
}

uint256 _periodRewards = rewardPerDevice[_projectId] *
(ioIDStore.projectActivedAmount(_projectId) - projectInvalidDevice[_projectId]);
uint256 _cap = projectCap[_projectId];
if (_cap != 0 && _periodRewards > _cap) {
_periodRewards = _cap;
}

return _claimablePeriods * _periodRewards;
}

function setInvalidDevice(uint256 _projectId, uint256 _amount) external onlyOwner {
require(ioIDStore.projectActivedAmount(_projectId) >= _amount, "invalid project");

Expand Down
19 changes: 19 additions & 0 deletions script/11_deploy_claim_vault_implementaion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { ethers } from 'hardhat';
require('dotenv').config();

async function main() {
if (!process.env.IOID_STORE) {
console.log(`Please provide IOID_STORE address`);
return;
}

const vault = await ethers.deployContract('PeriodClaimVault');
await vault.waitForDeployment();

console.log(`PeriodClaimVault implementation deployed to ${vault.target}`);
}

main().catch(err => {
console.error(err);
process.exitCode = 1;
});
8 changes: 8 additions & 0 deletions test/TestPeriodClaimVault.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,21 @@ describe('PeriodClaimVault tests', function () {
);

await time.increaseTo(startTimestamp + 86400 * 5 + 50000);
expect(await vault.claimableRewards(projectId)).to.be.equals(ethers.parseEther('0.9'));
await vault.connect(fakeRecipient).claim(projectId);
expect((await ethers.provider.getBalance(projectRecipient)) - balanceRecipient).to.be.equals(
((await ioIDStore.projectActivedAmount(projectId)) - (await vault.projectInvalidDevice(projectId))) *
(await vault.rewardPerDevice(projectId)) *
BigInt(4),
);

await vault.setProjectCap(projectId, ethers.parseEther('0.2'));
await expect(vault.setProjectCap(projectId, ethers.parseEther('0'))).to.revertedWith('invalid cap');
await expect(vault.setProjectCap(2, ethers.parseEther('10'))).to.revertedWith('invalid project');

await time.increaseTo(startTimestamp + 86400 * 8 + 50000);
expect(await vault.claimableRewards(projectId)).to.be.equals(ethers.parseEther('0.6'));

await vault.removeProject(projectId);
await expect(vault.claim(projectId)).to.revertedWith('invalid project');
});
Expand Down

0 comments on commit c3d37a6

Please sign in to comment.