[KMS-ETH]- WalletManager updated to Escrow

pull/195/head^2
szotov 2017-12-26 14:12:39 +03:00
parent 8b82ad01ce
commit bc6a293170
4 changed files with 58 additions and 152 deletions

View File

@ -89,7 +89,7 @@ contract Escrow is Miner, Ownable {
require(_value <= token.balanceOf(address(this)) &&
_value <= info.value.sub(lockedTokens));
// Checks if tokens are not locked or lock can be increased
// TODO add checking reward
// TODO add checking amount of reward
require(lockedTokens == 0 ||
info.releaseBlock >= block.number);
if (lockedTokens == 0) {
@ -174,24 +174,9 @@ contract Escrow is Miner, Ownable {
return getLockedTokens(_owner, block.number);
}
// /**
// * @notice Get locked tokens value for all owners in a specified moment in time
// * @param _blockNumber Block number for checking
// **/
// function getAllLockedTokens(uint256 _blockNumber)
// public constant returns (uint256 result)
// {
// var current = tokenOwners.step(0x0, true);
// while (current != 0x0) {
// result += getLockedTokens(current, _blockNumber);
// current = tokenOwners.step(current, true);
// }
// }
/**
* @notice Get locked tokens value for all owners in current period
**/
// TODO use confirmed periods
function getAllLockedTokens()
public constant returns (uint256 result)
{
@ -212,26 +197,8 @@ contract Escrow is Miner, Ownable {
var releasePeriod = info.releaseBlock / blocksPerPeriod + 1;
return block.number >= releasePeriod * blocksPerPeriod &&
info.numberConfirmedPeriods == 0;
// (info.numberConfirmedPeriods == 0 ||
// info.confirmedPeriods[info.numberConfirmedPeriods - 1] > releasePeriod);
}
// /**
// * @notice Penalize token owner
// * @param _user Token owner
// * @param _value Amount of tokens that will be confiscated
// **/
// function penalize(address _user, uint256 _value)
// onlyOwner
// public returns (bool success)
// {
// require(getLockedTokens(_user) >= _value);
// tokenInfo[_user].value = tokenInfo[_user].value.sub(_value);
// tokenInfo[_user].lockedValue = tokenInfo[_user].lockedValue.sub(_value);
// token.burn(_value);
// return true;
// }
/**
* @notice Confirm activity for future period
**/

View File

@ -88,7 +88,7 @@ contract WalletManager is Miner, Ownable {
}
require(_value <= token.balanceOf(wallet).sub(lockedTokens));
// Checks if tokens are not locked or lock can be increased
// TODO add checking reward
// TODO add checking amount of reward
require(lockedTokens == 0 ||
wallet.releaseBlock() >= block.number);
if (lockedTokens == 0) {
@ -134,20 +134,6 @@ contract WalletManager is Miner, Ownable {
return wallets[_owner].getLockedTokens(_blockNumber);
}
/**
* @notice Get locked tokens value for all owners in a specified moment in time
* @param _blockNumber Block number for checking
**/
function getAllLockedTokens(uint256 _blockNumber)
public constant returns (uint256 result)
{
var current = walletOwners.step(0x0, true);
while (current != 0x0) {
result += getLockedTokens(current, _blockNumber);
current = walletOwners.step(current, true);
}
}
/**
* @notice Get locked tokens value for owner
* @param _owner Tokens owner
@ -159,27 +145,13 @@ contract WalletManager is Miner, Ownable {
}
/**
* @notice Get locked tokens value for all owners
* @notice Get locked tokens value for all owners in current period
**/
function getAllLockedTokens()
public constant returns (uint256 result)
{
return getAllLockedTokens(block.number);
}
/**
* @notice Penalize token owner
* @param _user Token owner
* @param _value Amount of tokens that will be confiscated
**/
function penalize(address _user, uint256 _value)
onlyOwner
public returns (bool success)
{
require(walletOwners.valueExists(_user));
// require(getLockedTokens(_user) >= _value);
wallets[_user].burn(_value);
return true;
var currentPeriod = block.number / blocksPerPeriod;
return lockedPerPeriod[currentPeriod].totalLockedValue;
}
/**
@ -196,8 +168,6 @@ contract WalletManager is Miner, Ownable {
uint256 numberConfirmedPeriods = wallet.numberConfirmedPeriods();
return block.number >= releasePeriod * blocksPerPeriod &&
numberConfirmedPeriods == 0;
// (numberConfirmedPeriods == 0 ||
// wallet.confirmedPeriods(numberConfirmedPeriods - 1) > releasePeriod);
}
/**
@ -281,6 +251,7 @@ contract WalletManager is Miner, Ownable {
public constant returns (address o_stop, uint256 o_shift)
{
require(walletOwners.valueExists(_start));
var currentPeriod = block.number / blocksPerPeriod;
uint256 distance = 0;
uint256 lockedTokens = 0;
var current = _start;
@ -288,8 +259,17 @@ contract WalletManager is Miner, Ownable {
if (current == 0x0)
current = walletOwners.step(current, true);
while (true) {
lockedTokens = getLockedTokens(current);
while (current != 0x0) {
var wallet = wallets[current];
var numberConfirmedPeriods = wallet.numberConfirmedPeriods();
if (numberConfirmedPeriods == 0 ||
wallet.confirmedPeriods(numberConfirmedPeriods - 1) != currentPeriod &&
(numberConfirmedPeriods == 1 ||
wallet.confirmedPeriods(numberConfirmedPeriods - 2) != currentPeriod)) {
current = walletOwners.step(current, true);
continue;
}
lockedTokens = wallet.lockedValue();
if (_delta < distance + lockedTokens) {
o_stop = current;
o_shift = _delta - distance;

View File

@ -54,10 +54,8 @@ def test_escrow(web3, chain, token, escrow):
chain.wait.for_receipt(tx)
# Check that nothing is locked
# TODO fix getLockedTokens
assert escrow.call().getLockedTokens(ursula) == 0
assert escrow.call().getLockedTokens(alice) == 0
assert escrow.call().getAllLockedTokens() == 0
assert 0 == escrow.call().getLockedTokens(ursula)
assert 0 == escrow.call().getLockedTokens(alice)
# Ursula can't lock too low value
# TODO uncomment
@ -107,30 +105,9 @@ def test_escrow(web3, chain, token, escrow):
assert 1500 == token.call().balanceOf(escrow.address)
assert 9000 == token.call().balanceOf(ursula)
# TODO complete penalize
# And can't penalize anyone
# with pytest.raises(TransactionFailed):
# tx = escrow.transact({'from': ursula}).penalize(ursula, 100)
# chain.wait.for_receipt(tx)
# Creator can't penalize Ursula by burning tokens which exceeded her locked value
# with pytest.raises(TransactionFailed):
# tx = escrow.transact({'from': creator}).penalize(ursula, 1500)
# chain.wait.for_receipt(tx)
# But can penalize Ursula by burning some locked tokens
# tx = escrow.transact({'from': creator}).penalize(ursula, 100)
# chain.wait.for_receipt(tx)
# assert 1400 == token.call().balanceOf(escrow.address)
# assert 900 == escrow.call().getLockedTokens(ursula)
# assert 1400 == escrow.call().getAllLockedTokens()
# assert 900 == escrow.call().tokenInfo(ursula)[0]
# Wait 100 blocks
chain.wait.for_block(web3.eth.blockNumber + 100)
assert 0 == escrow.call().getLockedTokens(ursula)
# TODO fix getLockedTokens
# assert 500 == escrow.call().getAllLockedTokens()
# And Ursula can withdraw some tokens
tx = escrow.transact({'from': ursula}).withdraw(100)
@ -253,6 +230,9 @@ def test_mining(web3, chain, token, escrow):
tx = escrow.transact({'from': alice}).deposit(500, 200)
chain.wait.for_receipt(tx)
# Using locked tokens starts from next period
assert 0 == escrow.call().getAllLockedTokens()
# Give rights for mining
tx = token.transact({'from': creator}).addMiner(escrow.address)
chain.wait.for_receipt(tx)
@ -265,6 +245,7 @@ def test_mining(web3, chain, token, escrow):
# Ursula and Alice confirm next period
chain.wait.for_block(web3.eth.blockNumber + 50)
assert 1500 == escrow.call().getAllLockedTokens()
tx = escrow.transact({'from': ursula}).confirmActivity()
chain.wait.for_receipt(tx)
tx = escrow.transact({'from': alice}).confirmActivity()
@ -276,6 +257,7 @@ def test_mining(web3, chain, token, escrow):
# Ursula can't confirm next period because end of locking
chain.wait.for_block(web3.eth.blockNumber + 50)
assert 1500 == escrow.call().getAllLockedTokens()
with pytest.raises(TransactionFailed):
tx = escrow.transact({'from': ursula}).confirmActivity()
chain.wait.for_receipt(tx)
@ -292,24 +274,22 @@ def test_mining(web3, chain, token, escrow):
chain.wait.for_receipt(tx)
assert 9033 == token.call().balanceOf(ursula)
assert 9516 == token.call().balanceOf(alice)
# TODO fix
# assert 1500 == escrow.call().getAllLockedTokens()
# Ursula and Alice mint tokens for next period
chain.wait.for_block(web3.eth.blockNumber + 50)
assert 500 == escrow.call().getAllLockedTokens()
tx = escrow.transact({'from': ursula}).mint()
chain.wait.for_receipt(tx)
tx = escrow.transact({'from': alice}).mint()
chain.wait.for_receipt(tx)
assert 9038 == token.call().balanceOf(ursula)
assert 9532 == token.call().balanceOf(alice)
# TODO fix
# assert 500 == escrow.call().getAllLockedTokens()
# Alice confirm 2 periods and mint tokens
tx = escrow.transact({'from': alice}).confirmActivity()
chain.wait.for_receipt(tx)
chain.wait.for_block(web3.eth.blockNumber + 100)
assert 0 == escrow.call().getAllLockedTokens()
tx = escrow.transact({'from': alice}).mint()
chain.wait.for_receipt(tx)
assert 9038 == token.call().balanceOf(ursula)
@ -317,8 +297,6 @@ def test_mining(web3, chain, token, escrow):
alice_tokens = token.call().balanceOf(alice)
assert alice_tokens < 9633 # max minted tokens
assert alice_tokens > 9583 # min minted tokens
# TODO fix
# assert 0 == escrow.call().getAllLockedTokens()
# Ursula can't confirm and mint because no locked tokens
with pytest.raises(TransactionFailed):

View File

@ -32,8 +32,8 @@ def test_escrow(web3, chain, token, wallet_manager):
chain.wait.for_receipt(tx)
tx = token.transact({'from': creator}).transfer(alice, 10000)
chain.wait.for_receipt(tx)
assert token.call().balanceOf(ursula) == 10000
assert token.call().balanceOf(alice) == 10000
assert 10000 == token.call().balanceOf(ursula)
assert 10000 == token.call().balanceOf(alice)
# Ursula and Alice create wallets
contract_factory = chain.provider.get_contract_factory("Wallet")
@ -62,17 +62,17 @@ def test_escrow(web3, chain, token, wallet_manager):
# Ursula and Alice transfer some money to wallets
tx = token.transact({'from': ursula}).transfer(ursula_wallet.address, 1500)
chain.wait.for_receipt(tx)
assert token.call().balanceOf(ursula_wallet.address) == 1500
assert 1500 == token.call().balanceOf(ursula_wallet.address)
tx = token.transact({'from': alice}).transfer(alice_wallet.address, 500)
chain.wait.for_receipt(tx)
assert token.call().balanceOf(alice_wallet.address) == 500
assert 500 == token.call().balanceOf(alice_wallet.address)
# Ursula asks for refund
tx = ursula_wallet.transact({'from': ursula}).withdraw(500)
chain.wait.for_receipt(tx)
# and it works
assert token.call().balanceOf(ursula_wallet.address) == 1000
assert token.call().balanceOf(ursula) == 9000
assert 1000 == token.call().balanceOf(ursula_wallet.address)
assert 9000 == token.call().balanceOf(ursula)
# Alice can't withdraw from Ursula's wallet
with pytest.raises(TransactionFailed):
@ -80,9 +80,8 @@ def test_escrow(web3, chain, token, wallet_manager):
chain.wait.for_receipt(tx)
# Check that nothing is locked
assert ursula_wallet.call().getLockedTokens() == 0
assert alice_wallet.call().getLockedTokens() == 0
assert wallet_manager.call().getAllLockedTokens() == 0
assert 0 == ursula_wallet.call().getLockedTokens()
assert 0 == alice_wallet.call().getLockedTokens()
# Ursula can't lock too low value (less then rate)
# TODO uncomment
@ -93,51 +92,31 @@ def test_escrow(web3, chain, token, wallet_manager):
# Ursula and Alice lock some tokens for 100 and 200 blocks
tx = wallet_manager.transact({'from': ursula}).lock(1000, 100)
chain.wait.for_receipt(tx)
assert ursula_wallet.call().getLockedTokens() == 1000
assert alice_wallet.call().getLockedTokens() == 0
assert wallet_manager.call().getLockedTokens(ursula) == 1000
assert wallet_manager.call().getAllLockedTokens() == 1000
tx = wallet_manager.transact({'from': alice}).lock(500, 200)
chain.wait.for_receipt(tx)
assert ursula_wallet.call().getLockedTokens() == 1000
assert alice_wallet.call().getLockedTokens() == 500
assert wallet_manager.call().getLockedTokens(alice) == 500
assert wallet_manager.call().getAllLockedTokens() == 1500
# Checks locked tokens in next period
chain.wait.for_block(web3.eth.blockNumber + 50)
assert 1000 == ursula_wallet.call().getLockedTokens()
assert 500 == alice_wallet.call().getLockedTokens()
assert 1500 == wallet_manager.call().getAllLockedTokens()
# Ursula's withdrawal attempt won't succeed
with pytest.raises(TransactionFailed):
tx = ursula_wallet.transact({'from': ursula}).withdraw(100)
chain.wait.for_receipt(tx)
assert token.call().balanceOf(ursula_wallet.address) == 1000
assert token.call().balanceOf(ursula) == 9000
# And Ursula can't penalize anyone
with pytest.raises(TransactionFailed):
tx = wallet_manager.transact({'from': ursula}).penalize(ursula, 100)
chain.wait.for_receipt(tx)
# Creator can't penalize Ursula by burning tokens which exceeded her locked value
with pytest.raises(TransactionFailed):
tx = wallet_manager.transact({'from': creator}).penalize(ursula, 2000)
chain.wait.for_receipt(tx)
# But can penalize Ursula by burning some locked tokens
tx = wallet_manager.transact({'from': creator}).penalize(ursula, 100)
chain.wait.for_receipt(tx)
assert token.call().balanceOf(ursula_wallet.address) == 900
assert ursula_wallet.call().getLockedTokens() == 900
assert wallet_manager.call().getAllLockedTokens() == 1400
assert 1000 == token.call().balanceOf(ursula_wallet.address)
assert 9000 == token.call().balanceOf(ursula)
# Wait 100 blocks
chain.wait.for_block(web3.eth.blockNumber + 100)
assert ursula_wallet.call().getLockedTokens() == 0
assert wallet_manager.call().getAllLockedTokens() == 500
assert 0 == ursula_wallet.call().getLockedTokens()
# And Ursula can withdraw some tokens
tx = ursula_wallet.transact({'from': ursula}).withdraw(100)
chain.wait.for_receipt(tx)
assert token.call().balanceOf(ursula_wallet.address) == 800
assert token.call().balanceOf(ursula) == 9100
assert 900 == token.call().balanceOf(ursula_wallet.address)
assert 9100 == token.call().balanceOf(ursula)
# But Ursula can't lock some of tokens again without mining for locked value
with pytest.raises(TransactionFailed):
@ -149,14 +128,14 @@ def test_escrow(web3, chain, token, wallet_manager):
chain.wait.for_receipt(tx)
tx = wallet_manager.transact({'from': alice}).lock(500, 0)
chain.wait.for_receipt(tx)
assert wallet_manager.call().getLockedTokens(alice) == 1000
assert wallet_manager.call().getLockedTokens(alice, web3.eth.blockNumber + 100) == 0
assert 1000 == wallet_manager.call().getLockedTokens(alice)
assert 0 == wallet_manager.call().getLockedTokens(alice, web3.eth.blockNumber + 100)
# And increases locked blocks
tx = wallet_manager.transact({'from': alice}).lock(0, 100)
chain.wait.for_receipt(tx)
assert wallet_manager.call().getLockedTokens(alice) == 1000
assert wallet_manager.call().getLockedTokens(alice, web3.eth.blockNumber + 100) == 1000
assert wallet_manager.call().getLockedTokens(alice, web3.eth.blockNumber + 200) == 0
assert 1000 == wallet_manager.call().getLockedTokens(alice)
assert 1000 == wallet_manager.call().getLockedTokens(alice, web3.eth.blockNumber + 100)
assert 0 == wallet_manager.call().getLockedTokens(alice, web3.eth.blockNumber + 200)
# # Ursula can't destroy contract
# TODO fix bug
@ -197,6 +176,7 @@ def test_locked_distribution(web3, chain, token, wallet_manager):
tx = wallet_manager.transact({'from': addr}).lock(balance, 100)
chain.wait.for_receipt(tx)
chain.wait.for_block(web3.eth.blockNumber + 50)
n_locked = wallet_manager.call().getAllLockedTokens()
assert n_locked > 0
@ -256,6 +236,9 @@ def test_mining(web3, chain, token, wallet_manager):
tx = wallet_manager.transact({'from': alice}).lock(500, 200)
chain.wait.for_receipt(tx)
# Using locked tokens starts from next period
assert 0 == wallet_manager.call().getAllLockedTokens()
# Ursula can't use method from Miner contract
with pytest.raises(TypeError):
tx = wallet_manager.transact({'from': ursula}).mint(ursula, 1000, 1000, 1000, 1000)
@ -263,6 +246,7 @@ def test_mining(web3, chain, token, wallet_manager):
# Ursula and Alice confirm next period
chain.wait.for_block(web3.eth.blockNumber + 50)
assert 1500 == wallet_manager.call().getAllLockedTokens()
tx = wallet_manager.transact({'from': ursula}).confirmActivity()
chain.wait.for_receipt(tx)
tx = wallet_manager.transact({'from': alice}).confirmActivity()
@ -279,6 +263,7 @@ def test_mining(web3, chain, token, wallet_manager):
chain.wait.for_receipt(tx)
# But Alice can
# TODO test situation when only one confirmed
tx = wallet_manager.transact({'from': alice}).confirmActivity()
chain.wait.for_receipt(tx)
@ -289,24 +274,22 @@ def test_mining(web3, chain, token, wallet_manager):
chain.wait.for_receipt(tx)
assert 1033 == token.call().balanceOf(ursula_wallet.address)
assert 516 == token.call().balanceOf(alice_wallet.address)
# TODO fix
# assert 1500 == escrow.call().getAllLockedTokens()
# Ursula and Alice mint tokens for next period
chain.wait.for_block(web3.eth.blockNumber + 50)
assert 500 == wallet_manager.call().getAllLockedTokens()
tx = wallet_manager.transact({'from': ursula}).mint()
chain.wait.for_receipt(tx)
tx = wallet_manager.transact({'from': alice}).mint()
chain.wait.for_receipt(tx)
assert 1040 == token.call().balanceOf(ursula_wallet.address)
assert 532 == token.call().balanceOf(alice_wallet.address)
# TODO fix
# assert 500 == escrow.call().getAllLockedTokens()
# Alice confirm 2 periods and mint tokens
tx = wallet_manager.transact({'from': alice}).confirmActivity()
chain.wait.for_receipt(tx)
chain.wait.for_block(web3.eth.blockNumber + 100)
assert 0 == wallet_manager.call().getAllLockedTokens()
tx = wallet_manager.transact({'from': alice}).mint()
chain.wait.for_receipt(tx)
assert 1040 == token.call().balanceOf(ursula_wallet.address)
@ -314,8 +297,6 @@ def test_mining(web3, chain, token, wallet_manager):
alice_tokens = token.call().balanceOf(alice_wallet.address)
assert alice_tokens < 633 # max minted tokens
assert alice_tokens > 583 # min minted tokens
# TODO fix
# assert 0 == escrow.call().getAllLockedTokens()
# Ursula can't confirm and mint because no locked tokens
with pytest.raises(TransactionFailed):