Skip to content

Commit 6df8ac6

Browse files
committed
feat(reward-contracts): first draft without S curve
- tests + mock contracts included
1 parent 791b1ab commit 6df8ac6

File tree

7 files changed

+738
-136
lines changed

7 files changed

+738
-136
lines changed

contracts/reward/BlockReward.sol

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ pragma solidity ^0.5.4;
33
import "../interfaces/IBlockReward.sol";
44
import "../storage/EternalStorage.sol";
55
import "./SCurveProvider.sol";
6+
67
import "../libs/SafeMath.sol";
78

89

@@ -18,14 +19,17 @@ contract BlockReward is EternalStorage, SCurveProvider, IBlockReward {
1819
bytes32 internal constant MINTED_FOR_ACCOUNT_IN_BLOCK = "mintedForAccountInBlock";
1920
bytes32 internal constant MINTED_IN_BLOCK = "mintedInBlock";
2021

21-
uint256 public constant COMMUNITY_FUND_AMOUNT = 1 ether;
22+
// solhint-disable var-name-mixedcase
23+
24+
/// SYSTEM_ADDRESS: 2^160 - 2
2225
address internal SYSTEM_ADDRESS = 0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE;
23-
// Needs
24-
address public communityFund = 0x0000000000000000000000000000000000000000;
25-
26+
/// The constant amount that gets sent to the
27+
/// community fund with each new block. It is a constant
28+
/// value but can be set in the constructor.
29+
uint256 public communityFundAmount;
30+
address public communityFund;
2631
mapping(address => address) public payoutAddresses;
27-
28-
event Rewarded(address[] receivers, uint256[] rewards);
32+
// solhint-enable var-name-mixedcase
2933

3034
modifier onlySystem {
3135
require(
@@ -43,6 +47,13 @@ contract BlockReward is EternalStorage, SCurveProvider, IBlockReward {
4347
_;
4448
}
4549

50+
constructor(address _communityFundAddress, uint256 _communityFundAmount)
51+
public
52+
{
53+
communityFund = _communityFundAddress;
54+
communityFundAmount = _communityFundAmount;
55+
}
56+
4657
function setCommunityFund(address _newFund)
4758
external
4859
onlyCommunityFund
@@ -82,14 +93,10 @@ contract BlockReward is EternalStorage, SCurveProvider, IBlockReward {
8293
rewards[0] = getBlockReward(block.number);
8394

8495
receivers[1] = _getPayoutAddress(communityFund);
85-
rewards[1] = COMMUNITY_FUND_AMOUNT;
96+
rewards[1] = communityFundAmount;
8697

87-
_trackMinted(rewards[0], receivers[0]);
88-
_trackCommunityMinted(rewards[0], receivers[1]);
89-
90-
// We might take this out cause service transactions
91-
// cannot emit events
92-
emit Rewarded(receivers, rewards);
98+
_logMinted(rewards[0], receivers[0]);
99+
_logCommunityMinted(rewards[1], receivers[1]);
93100

94101
return (receivers, rewards);
95102
}
@@ -162,35 +169,35 @@ contract BlockReward is EternalStorage, SCurveProvider, IBlockReward {
162169
return _payoutAddress;
163170
}
164171

165-
function _trackCommunityMinted(uint256 _amount, address _account)
172+
function _logCommunityMinted(uint256 _amount, address _account)
166173
private
167174
{
168-
bytes32 hash;
175+
bytes32 _hash;
169176

170-
hash = MINTED_FOR_COMMUNITY;
171-
uintStorage[hash] = uintStorage[hash].add(_amount);
177+
_hash = MINTED_FOR_COMMUNITY;
178+
uintStorage[_hash] = uintStorage[_hash].add(_amount);
172179

173-
hash = keccak256(abi.encode(MINTED_FOR_COMMUNITY_FOR_ACCOUNT, _account));
174-
uintStorage[hash] = uintStorage[hash].add(_amount);
180+
_hash = keccak256(abi.encode(MINTED_FOR_COMMUNITY_FOR_ACCOUNT, _account));
181+
uintStorage[_hash] = uintStorage[_hash].add(_amount);
175182

176-
_trackMinted(_amount, _account);
183+
_logMinted(_amount, _account);
177184
}
178185

179-
function _trackMinted(uint256 _amount, address _account)
186+
function _logMinted(uint256 _amount, address _account)
180187
private
181188
{
182-
bytes32 hash;
189+
bytes32 _hash;
183190

184-
hash = keccak256(abi.encode(MINTED_FOR_ACCOUNT_IN_BLOCK, _account, block.number));
185-
uintStorage[hash] = _amount;
191+
_hash = keccak256(abi.encode(MINTED_FOR_ACCOUNT_IN_BLOCK, _account, block.number));
192+
uintStorage[_hash] = uintStorage[_hash].add(_amount);
186193

187-
hash = keccak256(abi.encode(MINTED_FOR_ACCOUNT, _account));
188-
uintStorage[hash] = uintStorage[hash].add(_amount);
194+
_hash = keccak256(abi.encode(MINTED_FOR_ACCOUNT, _account));
195+
uintStorage[_hash] = uintStorage[_hash].add(_amount);
189196

190-
hash = keccak256(abi.encode(MINTED_IN_BLOCK, block.number));
191-
uintStorage[hash] = uintStorage[hash].add(_amount);
197+
_hash = keccak256(abi.encode(MINTED_IN_BLOCK, block.number));
198+
uintStorage[_hash] = uintStorage[_hash].add(_amount);
192199

193-
hash = MINTED_TOTALLY;
194-
uintStorage[hash] = uintStorage[hash].add(_amount);
200+
_hash = MINTED_TOTALLY;
201+
uintStorage[_hash] = uintStorage[_hash].add(_amount);
195202
}
196203
}
Lines changed: 2 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,104 +1,13 @@
11
pragma solidity ^0.5.4;
22

3-
import "../libs/SafeMath.sol";
43

5-
6-
//solhint-disable max-line-length
74
contract SCurveProvider {
85

9-
/*
10-
using SafeMath for uint256;
11-
12-
uint256 internal blockTime ; //block time in seconds
13-
uint256 internal rewardDuration; //reward duration in years
14-
uint256 internal blocks; //'blockTime' seconds per block | 60min * 24h * 365d * 'rewardDuration'years
15-
uint256 internal block1; //block number for constant phase end
16-
uint256 internal block2; //block number to start asymptomical phase
17-
18-
uint256 internal quotient; // integral quotient to calibrate to defined reward tokens, is calculated by "CalculateReward"
19-
uint256 internal rewardtokens; // number of total reward tokens (in ether!)
20-
uint256 internal maxreward; //maximum reward in Wei, paid only in the constant phase, later it becomes less. Is calculated by "CalculateReward"
21-
22-
23-
constructor()
6+
function getBlockReward(uint256 _currentBlock)
247
public
25-
{
26-
blockTime = 5;
27-
rewardDuration = 10;
28-
blocks = ((((uint256(60).div(blockTime)).mul(60)).mul(24)).mul(365)).mul(rewardDuration);
29-
block1 = blocks.mul(t1);
30-
block2 = blocks.mul(t2);
31-
32-
quotient = 32586770;
33-
rewardtokens = 10000000 ether;
34-
maxreward = rewardtokens.mul(quotient) wei;
35-
}
36-
37-
function F1(uint256 _currentblock)
38-
internal
39-
view
40-
returns (uint256)
41-
{
42-
return maxreward;
43-
}
44-
45-
function F2(uint256 _currentblock)
46-
internal
478
view
489
returns (uint256)
49-
{
50-
// constants - can be outsourced into a init function
51-
uint256 _a = block2.sub(blocks);
52-
uint256 _b = block2.sub(block1);
53-
uint256 _c = blocks.mul(blocks.sub(block1.add(block2))) + block1.mul(block2);
54-
// help variable
55-
uint256 _d = block1.sub(currentblock);
56-
// calculation
57-
//final long y = (long) ((double) maxreward * d * d * a / c / b + maxreward);
58-
//final long y = maxreward * a * d * d / b / c + maxreward; //if numerical possible
59-
uint256 _y = maxreward.div(_c).mul(_a) * _d / _b * _d + maxreward;
60-
61-
return _y;
62-
}
63-
64-
function F3(uint256 currentblock)
65-
internal
66-
view
67-
returns (uint256)
68-
{
69-
// constants - can be outsourced into a init function
70-
final long c = blocks * (blocks - (block1 + block2)) + block1 * block2;
71-
// help variable
72-
final long d = blocks - currentblock;
73-
// calculation
74-
//final long y = (long) ((double) maxreward * d * d / c);
75-
//final long y = maxreward * d * d / c; //if numerical possible
76-
final long y = maxreward / c * d * d;
77-
78-
return y;
79-
}
80-
81-
function calculateBlockReward(uint256 _currentblock)
82-
internal
83-
view
84-
returns (uint256)
85-
{
86-
if (_currentblock < block1) {
87-
return F1(_currentblock);
88-
}
89-
else if (_currentblock < block2) {
90-
return F2(_currentblock);
91-
}
92-
return F3(_currentblock);
93-
}
94-
*/
95-
96-
function getBlockReward(uint256 _currentBlock)
97-
internal
98-
pure
99-
returns (uint256)
10010
{
10111
return 5;
10212
}
103-
}
104-
//solhint-enable max-line-length
13+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
const steps = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
2+
3+
function calculateBlockReward(_blockNumber) {
4+
const rem = _blockNumber % 100;
5+
6+
for (i = 0; i < steps.length; i++) {
7+
if (rem <= steps[i]) {
8+
return 110 - steps[i];
9+
}
10+
}
11+
return 0;
12+
}
13+
14+
module.exports = {
15+
calculateBlockReward
16+
};
Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,41 @@
1-
pragma solidity ^0.5.0;
1+
pragma solidity ^0.5.4;
22
import "../../../contracts/reward/BlockReward.sol";
33

44

55
contract MockReward is BlockReward {
66

7+
address private _tester;
8+
uint256[] public _steps;
9+
10+
constructor(address _communityFundAddress, uint256 _communityFundAmount)
11+
BlockReward(_communityFundAddress, _communityFundAmount)
12+
public
13+
{
14+
_tester = msg.sender;
15+
_steps = [uint256(10), 20, 30, 40, 50, 60, 70, 80, 90, 100];
16+
}
17+
718
function setSystemAddress(address _address)
819
public
920
{
21+
require(_tester == msg.sender, "Not the tester");
1022
SYSTEM_ADDRESS = _address;
1123
}
24+
25+
/// We mock the blockreward for the tests only
26+
function getBlockReward(uint256 _currentBlock)
27+
public
28+
view
29+
returns (uint256)
30+
{
31+
uint256 rem = _currentBlock % 100;
32+
33+
uint i;
34+
for (i = 0; i < _steps.length; i++) {
35+
if (rem <= _steps[i]) {
36+
return 110 - _steps[i];
37+
}
38+
}
39+
return 0;
40+
}
1241
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
pragma solidity ^0.5.4;
2+
import "../../../contracts/reward/BlockReward.sol";
3+
4+
5+
contract MockSystem {
6+
7+
event Rewarded(address[] receivers, uint256[] rewards);
8+
9+
address private _tester;
10+
BlockReward public _rewardContract;
11+
12+
modifier onlyTester() {
13+
require(msg.sender == _tester, "Not the tester");
14+
_;
15+
}
16+
17+
constructor(address _rContract)
18+
public
19+
{
20+
_tester = msg.sender;
21+
_rewardContract = BlockReward(_rContract);
22+
}
23+
24+
function setRewardContract(address _newAddress)
25+
onlyTester
26+
public
27+
{
28+
_rewardContract = BlockReward(_newAddress);
29+
}
30+
31+
function rewardWithEvent(address[] memory _benefactors, uint16[] memory _kind)
32+
public
33+
onlyTester
34+
{
35+
address[] memory _receivers;
36+
uint256[] memory _rewards;
37+
(_receivers, _rewards) = _rewardContract.reward(_benefactors, _kind);
38+
emit Rewarded(_receivers, _rewards);
39+
}
40+
}

0 commit comments

Comments
 (0)