tokenbridge-contracts/contracts/upgradeable_contracts/ValidatorsFeeManager.sol

70 lines
2.9 KiB
Solidity

pragma solidity 0.4.24;
import "./BaseFeeManager.sol";
import "../interfaces/IRewardableValidators.sol";
import "./ValidatorStorage.sol";
contract ValidatorsFeeManager is BaseFeeManager, ValidatorStorage {
bytes32 public constant REWARD_FOR_TRANSFERRING_FROM_HOME = 0x2a11db67c480122765825a7e4bc5428e8b7b9eca0d4e62b91aac194f99edd0d7; // keccak256(abi.encodePacked("reward-transferring-from-home"))
bytes32 public constant REWARD_FOR_TRANSFERRING_FROM_FOREIGN = 0xb14796d751eb4f2570065a479f9e526eabeb2077c564c8a1c5ea559883ea2fab; // keccak256(abi.encodePacked("reward-transferring-from-foreign"))
function distributeFeeFromAffirmation(uint256 _fee) external {
distributeFeeProportionally(_fee, REWARD_FOR_TRANSFERRING_FROM_FOREIGN);
}
function distributeFeeFromSignatures(uint256 _fee) external {
distributeFeeProportionally(_fee, REWARD_FOR_TRANSFERRING_FROM_HOME);
}
function rewardableValidatorContract() internal view returns (IRewardableValidators) {
return IRewardableValidators(addressStorage[VALIDATOR_CONTRACT]);
}
function distributeFeeProportionally(uint256 _fee, bytes32 _direction) internal {
IRewardableValidators validators = rewardableValidatorContract();
// solhint-disable-next-line var-name-mixedcase
address F_ADDR = 0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF;
uint256 numOfValidators = validators.validatorCount();
uint256 feePerValidator = _fee.div(numOfValidators);
uint256 randomValidatorIndex;
uint256 diff = _fee.sub(feePerValidator.mul(numOfValidators));
if (diff > 0) {
randomValidatorIndex = random(numOfValidators);
}
address nextValidator = validators.getNextValidator(F_ADDR);
require((nextValidator != F_ADDR) && (nextValidator != address(0)));
uint256 i = 0;
while (nextValidator != F_ADDR) {
uint256 feeToDistribute = feePerValidator;
if (diff > 0 && randomValidatorIndex == i) {
feeToDistribute = feeToDistribute.add(diff);
}
address rewardAddress = validators.getValidatorRewardAddress(nextValidator);
onFeeDistribution(rewardAddress, feeToDistribute, _direction);
nextValidator = validators.getNextValidator(nextValidator);
require(nextValidator != address(0));
i = i + 1;
}
}
function onFeeDistribution(address _rewardAddress, uint256 _fee, bytes32 _direction) internal {
if (_direction == REWARD_FOR_TRANSFERRING_FROM_FOREIGN) {
onAffirmationFeeDistribution(_rewardAddress, _fee);
} else {
onSignatureFeeDistribution(_rewardAddress, _fee);
}
}
/* solcov ignore next */
function onAffirmationFeeDistribution(address _rewardAddress, uint256 _fee) internal;
/* solcov ignore next */
function onSignatureFeeDistribution(address _rewardAddress, uint256 _fee) internal;
}