Skip to content

Commit

Permalink
Fix Bailsec Issue_12
Browse files Browse the repository at this point in the history
  • Loading branch information
evercoinx committed Oct 14, 2024
1 parent dce9957 commit 65124c9
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 14 deletions.
38 changes: 30 additions & 8 deletions contracts/MaticX.sol
Original file line number Diff line number Diff line change
Expand Up @@ -381,26 +381,31 @@ contract MaticX is
return rewards;
}

/// @notice Stake POL rewards and distribute fees to the treasury if any.
/// @notice Stakes POL rewards and distribute fees to the treasury if any.
/// @param _validatorId - Validator id to stake POL rewards
function stakeRewardsAndDistributeFees(
uint256 _validatorId
) external override nonReentrant whenNotPaused onlyRole(BOT) {
_stakeRewardsAndDistributeFees(_validatorId, true);
_stakeRewardsAndDistributeFees(_validatorId, true, true);
}

/// @notice Stake Matic rewards and distribute fees to the treasury if any.
/// @notice Stakes Matic rewards and distribute fees to the treasury if any.
/// @custom:deprecated
/// @param _validatorId - Validator id to stake Matic rewards
function stakeRewardsAndDistributeFeesMatic(
uint256 _validatorId
) external override nonReentrant whenNotPaused onlyRole(BOT) {
_stakeRewardsAndDistributeFees(_validatorId, false);
_stakeRewardsAndDistributeFees(_validatorId, false, true);
}

/// @notice Stakes token rewards and distribute fees to the treasury if any.
/// @param _validatorId - Validator id to stake toke rewards
/// @param _pol - If POL tokens are used for staking and fee distribution
/// @param _revertOnZeroReward - If revert on the zero reward or not
function _stakeRewardsAndDistributeFees(
uint256 _validatorId,
bool _pol
bool _pol,
bool _revertOnZeroReward
) private {
require(
validatorRegistry.validatorIdExists(_validatorId),
Expand All @@ -409,7 +414,12 @@ contract MaticX is

IERC20Upgradeable token = _pol ? polToken : maticToken;
uint256 reward = token.balanceOf(address(this));
require(reward > 0, "Reward is zero");
if (reward == 0) {
if (_revertOnZeroReward) {
revert("Reward is zero");
}
return;
}

uint256 treasuryFee = (reward * feePercent) / 100;
if (treasuryFee > 0) {
Expand All @@ -436,7 +446,7 @@ contract MaticX is
emit StakeRewards(_validatorId, amountToStake);
}

/// @notice Migrate all POL tokens to another validator.
/// @notice Migrates all POL tokens to another validator.
/// @param _fromValidatorId - Validator id to migrate POL tokens from
/// @param _toValidatorId - Validator id to migrate POL tokens to
/// @param _amount - Amount of POL tokens
Expand Down Expand Up @@ -468,11 +478,23 @@ contract MaticX is

/// @notice Sets a fee percent.
/// @param _feePercent - Fee percent (10 = 10%)
// slither-disable-next-line reentrancy-eth
function setFeePercent(
uint8 _feePercent
) external override onlyRole(DEFAULT_ADMIN_ROLE) {
) external override nonReentrant onlyRole(DEFAULT_ADMIN_ROLE) {
require(_feePercent <= 100, "Fee percent must not exceed 100");

uint256[] memory validatorIds = validatorRegistry.getValidators();
uint256 validatorIdCount = validatorIds.length;

for (uint256 i = 0; i < validatorIdCount; ) {
_stakeRewardsAndDistributeFees(validatorIds[i], true, false);

unchecked {
++i;
}
}

feePercent = _feePercent;
emit SetFeePercent(_feePercent);
}
Expand Down
6 changes: 3 additions & 3 deletions contracts/interfaces/IMaticX.sol
Original file line number Diff line number Diff line change
Expand Up @@ -134,16 +134,16 @@ interface IMaticX is IERC20Upgradeable {
uint256[] calldata _validatorIds
) external returns (uint256[] memory);

/// @notice Stake POL rewards and distribute fees to the treasury if any.
/// @notice Stakes POL rewards and distribute fees to the treasury if any.
/// @param _validatorId - Validator id to stake POL rewards
function stakeRewardsAndDistributeFees(uint256 _validatorId) external;

/// @notice Stake Matic rewards and distribute fees to the treasury if any.
/// @notice Stakes Matic rewards and distribute fees to the treasury if any.
/// @custom:deprecated
/// @param _validatorId - Validator id to stake Matic rewards
function stakeRewardsAndDistributeFeesMatic(uint256 _validatorId) external;

/// @notice Migrate all POL tokens to another validator.
/// @notice Migrates all POL tokens to another validator.
/// @param _fromValidatorId - Validator id to migrate POL tokens from
/// @param _toValidatorId - Validator id to migrate POL tokens to
/// @param _amount - Amount of POL tokens
Expand Down
2 changes: 1 addition & 1 deletion slither.config.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"compile_force_framework": "hardhat",
"detectors_to_exclude": "calls-loop,naming-convention,pragma,solc-version,unused-return,unused-state",
"detectors_to_exclude": "calls-loop,incorrect-equality,naming-convention,pragma,solc-version,unused-return,unused-state",
"include_paths": "(MaticX.sol|ValidatorRegistry.sol)",
"filter_paths": "(@openzeppelin/|lib/|mocks/|state-transfer/|tunnel/)"
}
37 changes: 35 additions & 2 deletions test/MaticX.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ describe("MaticX", function () {
const stakeAmount = ethers.utils.parseUnits("100", 18);
const tripleStakeAmount = stakeAmount.mul(3);
const version = "2";
const feePercent = 10;

async function deployFixture(callMaticXInitializeV2 = true) {
await reset(providerUrl, envVars.FORKING_BLOCK_NUMBER);
Expand Down Expand Up @@ -2460,16 +2461,48 @@ describe("MaticX", function () {
});

describe("Positive", function () {
it("Should emit the SetFeePercent event", async function () {
it("Should emit the SetFeePercent event if having zero rewards", async function () {
const { maticX, manager } = await loadFixture(deployFixture);

const feePercent = 100;
const promise = maticX
.connect(manager)
.setFeePercent(feePercent);
await expect(promise)
.to.emit(maticX, "SetFeePercent")
.withArgs(feePercent);

await expect(promise)
.not.to.emit(maticX, "StakeRewards")
.and.not.to.emit(maticX, "DistributeFees");
});

it("Should emit the SetFeePercent, StakeRewards and DistributeFees events if having non zero rewards", async function () {
const {
maticX,
pol,
polygonTreasury,
manager,
preferredDepositValidatorId,
} = await loadFixture(deployFixture);

await pol
.connect(polygonTreasury)
.transfer(maticX.address, stakeAmount);

const feeAmount = stakeAmount.mul(5).div(100);
const netStakeAmount = stakeAmount.sub(feeAmount);
const treasuryAddress = await maticX.treasury();

const promise = maticX
.connect(manager)
.setFeePercent(feePercent);
await expect(promise).to.emit(maticX, "SetFeePercent");

await expect(promise)
.to.emit(maticX, "StakeRewards")
.withArgs(preferredDepositValidatorId, netStakeAmount)
.and.to.emit(maticX, "DistributeFees")
.withArgs(treasuryAddress, feeAmount);
});
});
});
Expand Down

0 comments on commit 65124c9

Please sign in to comment.