From a0ae0e7a8913f41a33cc06939b8c51b813e5bcb6 Mon Sep 17 00:00:00 2001 From: Vadim Arasev Date: Fri, 18 May 2018 10:54:38 +0300 Subject: [PATCH] (Feature) BlockReward contract Relates to https://github.com/poanetwork/RFC/issues/14 --- contracts/BlockReward.sol | 77 +++++++++++++++++++++++++++ contracts/interfaces/IBlockReward.sol | 8 +++ 2 files changed, 85 insertions(+) create mode 100644 contracts/BlockReward.sol create mode 100644 contracts/interfaces/IBlockReward.sol diff --git a/contracts/BlockReward.sol b/contracts/BlockReward.sol new file mode 100644 index 0000000..f75ab24 --- /dev/null +++ b/contracts/BlockReward.sol @@ -0,0 +1,77 @@ +pragma solidity ^0.4.23; + +import "./interfaces/IBlockReward.sol"; +import "./interfaces/IKeysManager.sol"; +import "./interfaces/IProxyStorage.sol"; + + +contract BlockReward is IBlockReward { + address constant SYSTEM_ADDRESS = 0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE; + + IProxyStorage public proxyStorage; + address public emissionFunds; + uint256 public blockRewardAmount; + uint256 public emissionFundsAmount; + + modifier onlySystem { + require(msg.sender == SYSTEM_ADDRESS); + _; + } + + constructor( + address _proxyStorage, + address _emissionFunds, + uint256 _blockRewardAmount, + uint256 _emissionFundsAmount + ) public { + require(_proxyStorage != address(0)); + require(_blockRewardAmount != 0); + proxyStorage = IProxyStorage(_proxyStorage); + emissionFunds = _emissionFunds; + blockRewardAmount = _blockRewardAmount; + emissionFundsAmount = _emissionFundsAmount; + } + + function reward(address[] benefactors, uint16[] kind) + external + onlySystem + returns (address[], uint256[]) + { + require(benefactors.length == kind.length); + require(benefactors.length == 1); + require(kind[0] == 0); + + address miningKey = benefactors[0]; + address payoutKey = _getPayoutByMining(miningKey); + + require(payoutKey != address(0)); + + uint256 receiversLength = 2; + + if (emissionFunds == address(0) || emissionFundsAmount == 0) { + receiversLength = 1; + } + + address[] memory receivers = new address[](receiversLength); + uint256[] memory rewards = new uint256[](receiversLength); + + receivers[0] = payoutKey; + rewards[0] = blockRewardAmount; + + if (receiversLength == 2) { + receivers[1] = emissionFunds; + rewards[1] = emissionFundsAmount; + } + + return (receivers, rewards); + } + + function _getPayoutByMining(address _miningKey) + private + view + returns (address) + { + IKeysManager keysManager = IKeysManager(proxyStorage.getKeysManager()); + return keysManager.getPayoutByMining(_miningKey); + } +} diff --git a/contracts/interfaces/IBlockReward.sol b/contracts/interfaces/IBlockReward.sol new file mode 100644 index 0000000..6747c81 --- /dev/null +++ b/contracts/interfaces/IBlockReward.sol @@ -0,0 +1,8 @@ +pragma solidity ^0.4.23; + + +interface IBlockReward { + // Produce rewards for the given benefactors, with corresponding reward codes. + // Only callable by `SYSTEM_ADDRESS` + function reward(address[], uint16[]) external returns (address[], uint256[]); +}