mirror of https://github.com/nucypher/nucypher.git
[KMS-ETH]- Added reward for long locking
parent
1e8ee747bf
commit
567f17db0d
|
@ -4,7 +4,16 @@ from nkms_eth import blockchain
|
||||||
from nkms_eth import token
|
from nkms_eth import token
|
||||||
|
|
||||||
ESCROW_NAME = 'Escrow'
|
ESCROW_NAME = 'Escrow'
|
||||||
MINING_COEFF = [10 ** 9, 50, 1, 1, 1]
|
BLOCKS_PER_PERIOD = 50 # 6100
|
||||||
|
MIN_RELEASE_PERIODS = 1 # 30
|
||||||
|
MAX_AWARDED_PERIODS = 365
|
||||||
|
MINING_COEFF = [
|
||||||
|
BLOCKS_PER_PERIOD * MAX_AWARDED_PERIODS * 10 ** 9,
|
||||||
|
BLOCKS_PER_PERIOD,
|
||||||
|
MIN_RELEASE_PERIODS,
|
||||||
|
BLOCKS_PER_PERIOD * MAX_AWARDED_PERIODS,
|
||||||
|
MAX_AWARDED_PERIODS
|
||||||
|
]
|
||||||
NULL_ADDR = '0x' + '0' * 40
|
NULL_ADDR = '0x' + '0' * 40
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -191,7 +191,7 @@ contract Escrow is Miner, Ownable {
|
||||||
internal constant returns (uint256)
|
internal constant returns (uint256)
|
||||||
{
|
{
|
||||||
var info = tokenInfo[_owner];
|
var info = tokenInfo[_owner];
|
||||||
return _lockedTokens.div(info.releaseRate);
|
return _lockedTokens.divCeil(info.releaseRate).sub(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -376,6 +376,7 @@ contract Escrow is Miner, Ownable {
|
||||||
for(uint i = 0; i < numberPeriodsForMinting; ++i) {
|
for(uint i = 0; i < numberPeriodsForMinting; ++i) {
|
||||||
var period = info.confirmedPeriods[i].period;
|
var period = info.confirmedPeriods[i].period;
|
||||||
var lockedValue = info.confirmedPeriods[i].lockedValue;
|
var lockedValue = info.confirmedPeriods[i].lockedValue;
|
||||||
|
allLockedBlocks = allLockedBlocks.sub(blocksPerPeriod);
|
||||||
(, decimals) = mint(
|
(, decimals) = mint(
|
||||||
msg.sender,
|
msg.sender,
|
||||||
lockedValue,
|
lockedValue,
|
||||||
|
@ -383,7 +384,6 @@ contract Escrow is Miner, Ownable {
|
||||||
blocksPerPeriod,
|
blocksPerPeriod,
|
||||||
allLockedBlocks,
|
allLockedBlocks,
|
||||||
decimals);
|
decimals);
|
||||||
allLockedBlocks = allLockedBlocks.sub(blocksPerPeriod);
|
|
||||||
if (lockedPerPeriod[period].numberOwnersToBeRewarded > 1) {
|
if (lockedPerPeriod[period].numberOwnersToBeRewarded > 1) {
|
||||||
lockedPerPeriod[period].numberOwnersToBeRewarded--;
|
lockedPerPeriod[period].numberOwnersToBeRewarded--;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -70,12 +70,12 @@ contract Miner {
|
||||||
var maxValue = token.futureSupply()
|
var maxValue = token.futureSupply()
|
||||||
.mul(_currentLockedBlocks)
|
.mul(_currentLockedBlocks)
|
||||||
.mul(_lockedValue)
|
.mul(_lockedValue)
|
||||||
// .mul(allLockedBlocks)
|
.mul(allLockedBlocks)
|
||||||
.div(denominator);
|
.div(denominator);
|
||||||
var value = token.totalSupply()
|
var value = token.totalSupply()
|
||||||
.mul(_currentLockedBlocks)
|
.mul(_currentLockedBlocks)
|
||||||
.mul(_lockedValue)
|
.mul(_lockedValue)
|
||||||
// .mul(allLockedBlocks)
|
.mul(allLockedBlocks)
|
||||||
.div(denominator);
|
.div(denominator);
|
||||||
amount = maxValue.sub(value);
|
amount = maxValue.sub(value);
|
||||||
token.mint(_to, amount);
|
token.mint(_to, amount);
|
||||||
|
|
|
@ -151,7 +151,7 @@ contract Wallet is Ownable {
|
||||||
function calculateLockedPeriods(uint256 _lockedTokens)
|
function calculateLockedPeriods(uint256 _lockedTokens)
|
||||||
public constant returns (uint256)
|
public constant returns (uint256)
|
||||||
{
|
{
|
||||||
return _lockedTokens.div(releaseRate);
|
return _lockedTokens.divCeil(releaseRate).sub(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -189,6 +189,7 @@ contract WalletManager is Miner, Ownable {
|
||||||
|
|
||||||
for(uint i = 0; i < numberPeriodsForMinting; ++i) {
|
for(uint i = 0; i < numberPeriodsForMinting; ++i) {
|
||||||
var (period, lockedValue) = wallet.confirmedPeriods(i);
|
var (period, lockedValue) = wallet.confirmedPeriods(i);
|
||||||
|
allLockedBlocks = allLockedBlocks.sub(blocksPerPeriod);
|
||||||
(, decimals) = mint(
|
(, decimals) = mint(
|
||||||
wallet,
|
wallet,
|
||||||
lockedValue,
|
lockedValue,
|
||||||
|
@ -196,7 +197,6 @@ contract WalletManager is Miner, Ownable {
|
||||||
blocksPerPeriod,
|
blocksPerPeriod,
|
||||||
allLockedBlocks,
|
allLockedBlocks,
|
||||||
decimals);
|
decimals);
|
||||||
allLockedBlocks = allLockedBlocks.sub(blocksPerPeriod);
|
|
||||||
if (lockedPerPeriod[period].numberOwnersToBeRewarded > 1) {
|
if (lockedPerPeriod[period].numberOwnersToBeRewarded > 1) {
|
||||||
lockedPerPeriod[period].numberOwnersToBeRewarded--;
|
lockedPerPeriod[period].numberOwnersToBeRewarded--;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -17,7 +17,7 @@ def escrow(web3, chain, token):
|
||||||
creator = web3.eth.accounts[0]
|
creator = web3.eth.accounts[0]
|
||||||
# Creator deploys the escrow
|
# Creator deploys the escrow
|
||||||
escrow, _ = chain.provider.get_or_deploy_contract(
|
escrow, _ = chain.provider.get_or_deploy_contract(
|
||||||
'Escrow', deploy_args=[token.address, 10 ** 9, 50, 2, 1, 1],
|
'Escrow', deploy_args=[token.address, 4 * 50 * 10 ** 9, 50, 2, 4 * 50, 4],
|
||||||
deploy_transaction={'from': creator})
|
deploy_transaction={'from': creator})
|
||||||
return escrow
|
return escrow
|
||||||
|
|
||||||
|
@ -331,8 +331,8 @@ def test_mining(web3, chain, token, escrow):
|
||||||
chain.wait.for_receipt(tx)
|
chain.wait.for_receipt(tx)
|
||||||
tx = escrow.transact({'from': alice}).mint()
|
tx = escrow.transact({'from': alice}).mint()
|
||||||
chain.wait.for_receipt(tx)
|
chain.wait.for_receipt(tx)
|
||||||
assert 9033 == token.call().balanceOf(ursula)
|
assert 9050 == token.call().balanceOf(ursula)
|
||||||
assert 9517 == token.call().balanceOf(alice)
|
assert 9521 == token.call().balanceOf(alice)
|
||||||
|
|
||||||
# Only Ursula confirm activity for next period
|
# Only Ursula confirm activity for next period
|
||||||
tx = escrow.transact({'from': ursula}).switchLock()
|
tx = escrow.transact({'from': ursula}).switchLock()
|
||||||
|
@ -360,8 +360,8 @@ def test_mining(web3, chain, token, escrow):
|
||||||
with pytest.raises(TransactionFailed):
|
with pytest.raises(TransactionFailed):
|
||||||
tx = escrow.transact({'from': alice}).mint()
|
tx = escrow.transact({'from': alice}).mint()
|
||||||
chain.wait.for_receipt(tx)
|
chain.wait.for_receipt(tx)
|
||||||
assert 9133 == token.call().balanceOf(ursula)
|
assert 9163 == token.call().balanceOf(ursula)
|
||||||
assert 9517 == token.call().balanceOf(alice)
|
assert 9521 == token.call().balanceOf(alice)
|
||||||
|
|
||||||
# Alice confirm next period and mint tokens
|
# Alice confirm next period and mint tokens
|
||||||
tx = escrow.transact({'from': alice}).switchLock()
|
tx = escrow.transact({'from': alice}).switchLock()
|
||||||
|
@ -372,8 +372,8 @@ def test_mining(web3, chain, token, escrow):
|
||||||
assert 0 == escrow.call().getAllLockedTokens()
|
assert 0 == escrow.call().getAllLockedTokens()
|
||||||
tx = escrow.transact({'from': alice}).mint()
|
tx = escrow.transact({'from': alice}).mint()
|
||||||
chain.wait.for_receipt(tx)
|
chain.wait.for_receipt(tx)
|
||||||
assert 9133 == token.call().balanceOf(ursula)
|
assert 9163 == token.call().balanceOf(ursula)
|
||||||
assert 9617 == token.call().balanceOf(alice)
|
assert 9634 == token.call().balanceOf(alice)
|
||||||
|
|
||||||
# Ursula can't confirm and mint because no locked tokens
|
# Ursula can't confirm and mint because no locked tokens
|
||||||
with pytest.raises(TransactionFailed):
|
with pytest.raises(TransactionFailed):
|
||||||
|
@ -417,6 +417,6 @@ def test_mining(web3, chain, token, escrow):
|
||||||
# Alice can withdraw all
|
# Alice can withdraw all
|
||||||
tx = escrow.transact({'from': alice}).withdrawAll()
|
tx = escrow.transact({'from': alice}).withdrawAll()
|
||||||
chain.wait.for_receipt(tx)
|
chain.wait.for_receipt(tx)
|
||||||
assert 10117 == token.call().balanceOf(alice)
|
assert 10134 == token.call().balanceOf(alice)
|
||||||
|
|
||||||
# TODO test max confirmed periods
|
# TODO test max confirmed periods
|
||||||
|
|
|
@ -17,7 +17,7 @@ def wallet_manager(web3, chain, token):
|
||||||
creator = web3.eth.accounts[0]
|
creator = web3.eth.accounts[0]
|
||||||
# Creator deploys the wallet manager
|
# Creator deploys the wallet manager
|
||||||
wallet_manager_contract, _ = chain.provider.get_or_deploy_contract(
|
wallet_manager_contract, _ = chain.provider.get_or_deploy_contract(
|
||||||
'WalletManager', deploy_args=[token.address, 10 ** 9, 50, 2, 1, 1],
|
'WalletManager', deploy_args=[token.address, 4 * 50 * 10 ** 9, 50, 2, 4 * 50, 4],
|
||||||
deploy_transaction={'from': creator, 'gas': 4000000})
|
deploy_transaction={'from': creator, 'gas': 4000000})
|
||||||
return wallet_manager_contract
|
return wallet_manager_contract
|
||||||
|
|
||||||
|
@ -374,8 +374,8 @@ def test_mining(web3, chain, token, wallet_manager):
|
||||||
chain.wait.for_receipt(tx)
|
chain.wait.for_receipt(tx)
|
||||||
tx = wallet_manager.transact({'from': alice}).mint()
|
tx = wallet_manager.transact({'from': alice}).mint()
|
||||||
chain.wait.for_receipt(tx)
|
chain.wait.for_receipt(tx)
|
||||||
assert 1033 == token.call().balanceOf(ursula_wallet.address)
|
assert 1050 == token.call().balanceOf(ursula_wallet.address)
|
||||||
assert 517 == token.call().balanceOf(alice_wallet.address)
|
assert 521 == token.call().balanceOf(alice_wallet.address)
|
||||||
|
|
||||||
# Only Ursula confirm activity for next period
|
# Only Ursula confirm activity for next period
|
||||||
tx = ursula_wallet.transact({'from': ursula}).switchLock()
|
tx = ursula_wallet.transact({'from': ursula}).switchLock()
|
||||||
|
@ -403,8 +403,8 @@ def test_mining(web3, chain, token, wallet_manager):
|
||||||
with pytest.raises(TransactionFailed):
|
with pytest.raises(TransactionFailed):
|
||||||
tx = wallet_manager.transact({'from': alice}).mint()
|
tx = wallet_manager.transact({'from': alice}).mint()
|
||||||
chain.wait.for_receipt(tx)
|
chain.wait.for_receipt(tx)
|
||||||
assert 1133 == token.call().balanceOf(ursula_wallet.address)
|
assert 1163 == token.call().balanceOf(ursula_wallet.address)
|
||||||
assert 517 == token.call().balanceOf(alice_wallet.address)
|
assert 521 == token.call().balanceOf(alice_wallet.address)
|
||||||
|
|
||||||
# Alice confirm next period and mint tokens
|
# Alice confirm next period and mint tokens
|
||||||
tx = alice_wallet.transact({'from': alice}).switchLock()
|
tx = alice_wallet.transact({'from': alice}).switchLock()
|
||||||
|
@ -415,8 +415,8 @@ def test_mining(web3, chain, token, wallet_manager):
|
||||||
assert 0 == wallet_manager.call().getAllLockedTokens()
|
assert 0 == wallet_manager.call().getAllLockedTokens()
|
||||||
tx = wallet_manager.transact({'from': alice}).mint()
|
tx = wallet_manager.transact({'from': alice}).mint()
|
||||||
chain.wait.for_receipt(tx)
|
chain.wait.for_receipt(tx)
|
||||||
assert 1133 == token.call().balanceOf(ursula_wallet.address)
|
assert 1163 == token.call().balanceOf(ursula_wallet.address)
|
||||||
assert 617 == token.call().balanceOf(alice_wallet.address)
|
assert 634 == token.call().balanceOf(alice_wallet.address)
|
||||||
|
|
||||||
# Ursula can't confirm and mint because no locked tokens
|
# Ursula can't confirm and mint because no locked tokens
|
||||||
with pytest.raises(TransactionFailed):
|
with pytest.raises(TransactionFailed):
|
||||||
|
@ -471,8 +471,8 @@ def test_mining(web3, chain, token, wallet_manager):
|
||||||
# TODO complete method
|
# TODO complete method
|
||||||
# tx = wallet_manager.transact({'from': alice}).withdrawAll()
|
# tx = wallet_manager.transact({'from': alice}).withdrawAll()
|
||||||
# chain.wait.for_receipt(tx)
|
# chain.wait.for_receipt(tx)
|
||||||
tx = alice_wallet.transact({'from': alice}).withdraw(617)
|
tx = alice_wallet.transact({'from': alice}).withdraw(634)
|
||||||
chain.wait.for_receipt(tx)
|
chain.wait.for_receipt(tx)
|
||||||
assert 10117 == token.call().balanceOf(alice)
|
assert 10134 == token.call().balanceOf(alice)
|
||||||
|
|
||||||
# TODO test max confirmed periods
|
# TODO test max confirmed periods
|
||||||
|
|
|
@ -18,7 +18,7 @@ def test_miner(web3, chain, token):
|
||||||
|
|
||||||
# Creator deploys the miner
|
# Creator deploys the miner
|
||||||
miner, _ = chain.provider.get_or_deploy_contract(
|
miner, _ = chain.provider.get_or_deploy_contract(
|
||||||
'MinerTest', deploy_args=[token.address, 10 ** 41, 1, 1],
|
'MinerTest', deploy_args=[token.address, 10 ** 48, 10 ** 7, 10 ** 7],
|
||||||
deploy_transaction={'from': creator})
|
deploy_transaction={'from': creator})
|
||||||
|
|
||||||
# Give rights for mining
|
# Give rights for mining
|
||||||
|
@ -50,3 +50,13 @@ def test_miner(web3, chain, token):
|
||||||
chain.wait.for_receipt(tx)
|
chain.wait.for_receipt(tx)
|
||||||
assert 50 == token.call().balanceOf(ursula)
|
assert 50 == token.call().balanceOf(ursula)
|
||||||
assert 10 ** 30 + 50 == token.call().totalSupply()
|
assert 10 ** 30 + 50 == token.call().totalSupply()
|
||||||
|
|
||||||
|
tx = miner.transact().testMint(ursula, 500, 500, 200, 10 ** 7, 0)
|
||||||
|
chain.wait.for_receipt(tx)
|
||||||
|
assert 130 == token.call().balanceOf(ursula)
|
||||||
|
assert 10 ** 30 + 130 == token.call().totalSupply()
|
||||||
|
|
||||||
|
tx = miner.transact().testMint(ursula, 500, 500, 200, 2 * 10 ** 7, 0)
|
||||||
|
chain.wait.for_receipt(tx)
|
||||||
|
assert 210 == token.call().balanceOf(ursula)
|
||||||
|
assert 10 ** 30 + 210 == token.call().totalSupply()
|
||||||
|
|
|
@ -35,7 +35,7 @@ def test_select_ursulas(chain):
|
||||||
# Create a random set of miners (we have 9 in total)
|
# Create a random set of miners (we have 9 in total)
|
||||||
for u in chain.web3.eth.accounts[1:]:
|
for u in chain.web3.eth.accounts[1:]:
|
||||||
ursula.lock((10 + random.randrange(9000)) * M, 100, u)
|
ursula.lock((10 + random.randrange(9000)) * M, 100, u)
|
||||||
chain.wait.for_block(chain.web3.eth.blockNumber + 50)
|
chain.wait.for_block(chain.web3.eth.blockNumber + escrow.BLOCKS_PER_PERIOD)
|
||||||
|
|
||||||
miners = escrow.sample(3)
|
miners = escrow.sample(3)
|
||||||
assert len(miners) == 3
|
assert len(miners) == 3
|
||||||
|
@ -57,7 +57,7 @@ def test_mine_withdraw(chain):
|
||||||
for u in chain.web3.eth.accounts[1:]:
|
for u in chain.web3.eth.accounts[1:]:
|
||||||
ursula.lock((10 + random.randrange(9000)) * M, 1, u)
|
ursula.lock((10 + random.randrange(9000)) * M, 1, u)
|
||||||
|
|
||||||
chain.wait.for_block(chain.web3.eth.blockNumber + 100)
|
chain.wait.for_block(chain.web3.eth.blockNumber + 2 * escrow.BLOCKS_PER_PERIOD)
|
||||||
|
|
||||||
ursula.mine(addr)
|
ursula.mine(addr)
|
||||||
ursula.withdraw(addr)
|
ursula.withdraw(addr)
|
||||||
|
|
Loading…
Reference in New Issue