[KMS-ETH]- Added release rate recalculating

pull/195/head^2
szotov 2018-01-10 15:06:51 +03:00
parent b208d4de7b
commit 14c0cb99a0
4 changed files with 88 additions and 66 deletions

View File

@ -186,7 +186,8 @@ contract Escrow is Miner, Ownable {
require(tokenOwners.sizeOf() < MAX_OWNERS);
tokenOwners.push(msg.sender, true);
}
tokenInfo[msg.sender].value = tokenInfo[msg.sender].value.add(_value);
var info = tokenInfo[msg.sender];
info.value = info.value.add(_value);
token.safeTransferFrom(msg.sender, address(this), _value);
lock(_value, _periods);
}
@ -214,6 +215,8 @@ contract Escrow is Miner, Ownable {
info.lockedValue = lockedTokens.add(_value);
var period = Math.max256(info.releasePeriod, currentPeriod);
info.releasePeriod = period.add(_periods);
info.releaseRate = Math.max256(
info.releaseRate, info.lockedValue.div(minReleasePeriods));
}
confirmActivity(info.lockedValue);

View File

@ -162,6 +162,8 @@ contract Wallet is Ownable {
lockedValue = lockedTokens.add(_value);
var period = Math.max256(releasePeriod, currentPeriod);
releasePeriod = period.add(_periods);
releaseRate = Math.max256(
releaseRate, lockedValue.div(minReleasePeriods));
}
}

View File

@ -39,9 +39,9 @@ def test_escrow(web3, chain, token, escrow):
tx = token.transact({'from': ursula}).approve(escrow.address, 2500)
chain.wait.for_receipt(tx)
assert 2500 == token.call().allowance(ursula, escrow.address)
tx = token.transact({'from': alice}).approve(escrow.address, 1000)
tx = token.transact({'from': alice}).approve(escrow.address, 1100)
chain.wait.for_receipt(tx)
assert 1000 == token.call().allowance(alice, escrow.address)
assert 1100 == token.call().allowance(alice, escrow.address)
# Ursula's withdrawal attempt won't succeed because nothing to withdraw
with pytest.raises(TransactionFailed):
@ -69,11 +69,16 @@ def test_escrow(web3, chain, token, escrow):
assert 1000 == token.call().balanceOf(escrow.address)
assert 9000 == token.call().balanceOf(ursula)
assert 1000 == escrow.call().getLockedTokens(ursula)
assert 500 == escrow.call().calculateLockedTokens(ursula, 3)
assert 0 == escrow.call().calculateLockedTokens(ursula, 4)
tx = escrow.transact({'from': alice}).deposit(500, 6)
chain.wait.for_receipt(tx)
assert 500 == escrow.call().getLockedTokens(alice)
assert 1500 == token.call().balanceOf(escrow.address)
assert 9500 == token.call().balanceOf(alice)
assert 500 == escrow.call().getLockedTokens(alice)
assert 500 == escrow.call().calculateLockedTokens(alice, 6)
assert 250 == escrow.call().calculateLockedTokens(alice, 7)
assert 0 == escrow.call().calculateLockedTokens(alice, 8)
# Checks locked tokens in next period
chain.wait.for_block(web3.eth.blockNumber + 50)
@ -95,6 +100,7 @@ def test_escrow(web3, chain, token, escrow):
chain.wait.for_receipt(tx)
assert 2000 == token.call().balanceOf(escrow.address)
assert 8500 == token.call().balanceOf(ursula)
assert 750 == escrow.call().calculateLockedTokens(ursula, 2)
# Wait 50 blocks and checks locking
chain.wait.for_block(web3.eth.blockNumber + 50)
@ -104,8 +110,8 @@ def test_escrow(web3, chain, token, escrow):
tx = escrow.transact({'from': ursula}).confirmActivity()
chain.wait.for_receipt(tx)
chain.wait.for_block(web3.eth.blockNumber + 50)
assert 1000 == escrow.call().getLockedTokens(ursula)
assert 500 == escrow.call().calculateLockedTokens(ursula, 1)
assert 750 == escrow.call().getLockedTokens(ursula)
assert 0 == escrow.call().calculateLockedTokens(ursula, 1)
# And Ursula can withdraw some tokens
tx = escrow.transact({'from': ursula}).withdraw(100)
@ -125,24 +131,26 @@ def test_escrow(web3, chain, token, escrow):
chain.wait.for_receipt(tx)
# Locked tokens will be updated in next period
assert 1000 == escrow.call().getLockedTokens(ursula)
assert 1100 == escrow.call().calculateLockedTokens(ursula, 1)
assert 100 == escrow.call().calculateLockedTokens(ursula, 3)
assert 0 == escrow.call().calculateLockedTokens(ursula, 4)
chain.wait.for_block(web3.eth.blockNumber + 50)
assert 1100 == escrow.call().getLockedTokens(ursula)
# Release rate will be updated too because of end of previous locking
assert 750 == escrow.call().getLockedTokens(ursula)
assert 600 == escrow.call().calculateLockedTokens(ursula, 1)
assert 300 == escrow.call().calculateLockedTokens(ursula, 2)
assert 0 == escrow.call().calculateLockedTokens(ursula, 3)
chain.wait.for_block(web3.eth.blockNumber + 50)
assert 600 == escrow.call().getLockedTokens(ursula)
assert 300 == escrow.call().calculateLockedTokens(ursula, 1)
assert 0 == escrow.call().calculateLockedTokens(ursula, 2)
# Ursula can increase lock
tx = escrow.transact({'from': ursula}).lock(500, 2)
chain.wait.for_receipt(tx)
assert 1100 == escrow.call().getLockedTokens(ursula)
assert 1100 == escrow.call().calculateLockedTokens(ursula, 1)
assert 1100 == escrow.call().calculateLockedTokens(ursula, 2)
assert 600 == escrow.call().calculateLockedTokens(ursula, 3)
assert 0 == escrow.call().calculateLockedTokens(ursula, 5)
assert 600 == escrow.call().getLockedTokens(ursula)
assert 800 == escrow.call().calculateLockedTokens(ursula, 1)
assert 800 == escrow.call().calculateLockedTokens(ursula, 2)
assert 400 == escrow.call().calculateLockedTokens(ursula, 3)
assert 0 == escrow.call().calculateLockedTokens(ursula, 4)
chain.wait.for_block(web3.eth.blockNumber + 50)
assert 1100 == escrow.call().getLockedTokens(ursula)
assert 800 == escrow.call().getLockedTokens(ursula)
# Alice can't deposit too low value (less then rate)
# TODO uncomment after completing logic
@ -155,8 +163,8 @@ def test_escrow(web3, chain, token, escrow):
chain.wait.for_receipt(tx)
assert 500 == escrow.call().getLockedTokens(alice)
assert 1000 == escrow.call().calculateLockedTokens(alice, 1)
assert 750 == escrow.call().calculateLockedTokens(alice, 2)
assert 0 == escrow.call().calculateLockedTokens(alice, 5)
assert 500 == escrow.call().calculateLockedTokens(alice, 2)
assert 0 == escrow.call().calculateLockedTokens(alice, 3)
chain.wait.for_block(web3.eth.blockNumber + 50)
assert 1000 == escrow.call().getLockedTokens(alice)
@ -164,10 +172,17 @@ def test_escrow(web3, chain, token, escrow):
tx = escrow.transact({'from': alice}).lock(0, 2)
chain.wait.for_receipt(tx)
assert 1000 == escrow.call().getLockedTokens(alice)
assert 750 == escrow.call().calculateLockedTokens(alice, 1)
assert 750 == escrow.call().calculateLockedTokens(alice, 2)
assert 250 == escrow.call().calculateLockedTokens(alice, 4)
assert 0 == escrow.call().calculateLockedTokens(alice, 5)
assert 500 == escrow.call().calculateLockedTokens(alice, 1)
assert 500 == escrow.call().calculateLockedTokens(alice, 2)
assert 0 == escrow.call().calculateLockedTokens(alice, 3)
# Alice increases lock by small amount of tokens
tx = escrow.transact({'from': alice}).deposit(100, 0)
chain.wait.for_receipt(tx)
assert 600 == escrow.call().calculateLockedTokens(alice, 1)
assert 600 == escrow.call().calculateLockedTokens(alice, 2)
assert 100 == escrow.call().calculateLockedTokens(alice, 3)
assert 0 == escrow.call().calculateLockedTokens(alice, 4)
# Ursula can't destroy contract
with pytest.raises(TransactionFailed):
@ -357,23 +372,20 @@ def test_mining(web3, chain, token, escrow):
chain.wait.for_receipt(tx)
assert 600 == escrow.call().getLockedTokens(ursula)
assert 600 == escrow.call().calculateLockedTokens(ursula, 2)
assert 350 == escrow.call().calculateLockedTokens(ursula, 5)
assert 100 == escrow.call().calculateLockedTokens(ursula, 6)
assert 0 == escrow.call().calculateLockedTokens(ursula, 7)
assert 300 == escrow.call().calculateLockedTokens(ursula, 5)
assert 0 == escrow.call().calculateLockedTokens(ursula, 6)
tx = escrow.transact({'from': ursula}).lock(0, 2)
chain.wait.for_receipt(tx)
assert 600 == escrow.call().getLockedTokens(ursula)
assert 600 == escrow.call().calculateLockedTokens(ursula, 5)
assert 350 == escrow.call().calculateLockedTokens(ursula, 7)
assert 100 == escrow.call().calculateLockedTokens(ursula, 8)
assert 300 == escrow.call().calculateLockedTokens(ursula, 7)
assert 0 == escrow.call().calculateLockedTokens(ursula, 9)
tx = escrow.transact({'from': ursula}).lock(100, 1)
chain.wait.for_receipt(tx)
assert 700 == escrow.call().getLockedTokens(ursula)
assert 700 == escrow.call().calculateLockedTokens(ursula, 6)
assert 450 == escrow.call().calculateLockedTokens(ursula, 8)
assert 200 == escrow.call().calculateLockedTokens(ursula, 9)
assert 0 == escrow.call().calculateLockedTokens(ursula, 10)
assert 350 == escrow.call().calculateLockedTokens(ursula, 8)
assert 0 == escrow.call().calculateLockedTokens(ursula, 9)
# Alice can withdraw all
tx = escrow.transact({'from': alice}).withdrawAll()

View File

@ -121,19 +121,19 @@ def test_escrow(web3, chain, token, wallet_manager):
# Wait 50 blocks and checks locking
chain.wait.for_block(web3.eth.blockNumber + 50)
assert 1500 == ursula_wallet.call().getLockedTokens()
assert 1000 == ursula_wallet.call().calculateLockedTokens(web3.eth.blockNumber // 50, 1500, 1)
assert 1000 == ursula_wallet.call().calculateLockedTokens(1)
assert 500 == ursula_wallet.call().calculateLockedTokens(2)
assert 750 == ursula_wallet.call().calculateLockedTokens(web3.eth.blockNumber // 50, 1500, 1)
assert 750 == ursula_wallet.call().calculateLockedTokens(1)
assert 0 == ursula_wallet.call().calculateLockedTokens(2)
# Confirm activity and wait 50 blocks
tx = wallet_manager.transact({'from': ursula}).confirmActivity()
chain.wait.for_receipt(tx)
assert 1500 == ursula_wallet.call().getLockedTokens()
assert 1000 == ursula_wallet.call().calculateLockedTokens(1)
assert 500 == ursula_wallet.call().calculateLockedTokens(2)
assert 750 == ursula_wallet.call().calculateLockedTokens(1)
assert 0 == ursula_wallet.call().calculateLockedTokens(2)
chain.wait.for_block(web3.eth.blockNumber + 50)
assert 1000 == ursula_wallet.call().getLockedTokens()
assert 500 == ursula_wallet.call().calculateLockedTokens(1)
assert 750 == ursula_wallet.call().getLockedTokens()
assert 0 == ursula_wallet.call().calculateLockedTokens(1)
# And Ursula can withdraw some tokens
tx = ursula_wallet.transact({'from': ursula}).withdraw(100)
@ -157,24 +157,25 @@ def test_escrow(web3, chain, token, wallet_manager):
chain.wait.for_receipt(tx)
# Locked tokens will be updated in next period
assert 1000 == ursula_wallet.call().getLockedTokens()
assert 1100 == ursula_wallet.call().calculateLockedTokens(1)
assert 100 == ursula_wallet.call().calculateLockedTokens(3)
assert 0 == ursula_wallet.call().calculateLockedTokens(4)
chain.wait.for_block(web3.eth.blockNumber + 50)
assert 1100 == ursula_wallet.call().getLockedTokens()
assert 750 == ursula_wallet.call().getLockedTokens()
assert 600 == ursula_wallet.call().calculateLockedTokens(1)
assert 300 == ursula_wallet.call().calculateLockedTokens(2)
assert 0 == ursula_wallet.call().calculateLockedTokens(3)
chain.wait.for_block(web3.eth.blockNumber + 50)
assert 600 == ursula_wallet.call().getLockedTokens()
assert 300 == ursula_wallet.call().calculateLockedTokens(1)
assert 0 == ursula_wallet.call().calculateLockedTokens(2)
# Ursula can increase lock
tx = wallet_manager.transact({'from': ursula}).lock(500, 2)
chain.wait.for_receipt(tx)
assert 1100 == ursula_wallet.call().getLockedTokens()
assert 1100 == ursula_wallet.call().calculateLockedTokens(1)
assert 1100 == ursula_wallet.call().calculateLockedTokens(2)
assert 600 == ursula_wallet.call().calculateLockedTokens(3)
assert 0 == ursula_wallet.call().calculateLockedTokens(5)
assert 600 == ursula_wallet.call().getLockedTokens()
assert 800 == ursula_wallet.call().calculateLockedTokens(1)
assert 800 == ursula_wallet.call().calculateLockedTokens(2)
assert 400 == ursula_wallet.call().calculateLockedTokens(3)
assert 0 == ursula_wallet.call().calculateLockedTokens(4)
chain.wait.for_block(web3.eth.blockNumber + 50)
assert 1100 == ursula_wallet.call().getLockedTokens()
assert 800 == ursula_wallet.call().getLockedTokens()
# Alice can't deposit too low value (less then rate)
# TODO uncomment after completing logic
@ -189,8 +190,8 @@ def test_escrow(web3, chain, token, wallet_manager):
chain.wait.for_receipt(tx)
assert 500 == alice_wallet.call().getLockedTokens()
assert 1000 == alice_wallet.call().calculateLockedTokens(1)
assert 750 == alice_wallet.call().calculateLockedTokens(2)
assert 0 == alice_wallet.call().calculateLockedTokens(5)
assert 500 == alice_wallet.call().calculateLockedTokens(2)
assert 0 == alice_wallet.call().calculateLockedTokens(3)
chain.wait.for_block(web3.eth.blockNumber + 50)
assert 1000 == alice_wallet.call().getLockedTokens()
@ -198,10 +199,17 @@ def test_escrow(web3, chain, token, wallet_manager):
tx = wallet_manager.transact({'from': alice}).lock(0, 2)
chain.wait.for_receipt(tx)
assert 1000 == alice_wallet.call().getLockedTokens()
assert 750 == alice_wallet.call().calculateLockedTokens(1)
assert 750 == alice_wallet.call().calculateLockedTokens(2)
assert 250 == alice_wallet.call().calculateLockedTokens(4)
assert 0 == alice_wallet.call().calculateLockedTokens(5)
assert 500 == alice_wallet.call().calculateLockedTokens(1)
assert 500 == alice_wallet.call().calculateLockedTokens(2)
assert 0 == alice_wallet.call().calculateLockedTokens(3)
# Alice increases lock by small amount of tokens
tx = wallet_manager.transact({'from': alice}).lock(100, 0)
chain.wait.for_receipt(tx)
assert 600 == alice_wallet.call().calculateLockedTokens(1)
assert 600 == alice_wallet.call().calculateLockedTokens(2)
assert 100 == alice_wallet.call().calculateLockedTokens(3)
assert 0 == alice_wallet.call().calculateLockedTokens(4)
# Ursula can't destroy contract
with pytest.raises(TransactionFailed):
@ -409,23 +417,20 @@ def test_mining(web3, chain, token, wallet_manager):
chain.wait.for_receipt(tx)
assert 600 == ursula_wallet.call().getLockedTokens()
assert 600 == ursula_wallet.call().calculateLockedTokens(2)
assert 350 == ursula_wallet.call().calculateLockedTokens(5)
assert 100 == ursula_wallet.call().calculateLockedTokens(6)
assert 0 == ursula_wallet.call().calculateLockedTokens(7)
assert 300 == ursula_wallet.call().calculateLockedTokens(5)
assert 0 == ursula_wallet.call().calculateLockedTokens(6)
tx = wallet_manager.transact({'from': ursula}).lock(0, 2)
chain.wait.for_receipt(tx)
assert 600 == ursula_wallet.call().getLockedTokens()
assert 600 == ursula_wallet.call().calculateLockedTokens(5)
assert 350 == ursula_wallet.call().calculateLockedTokens(7)
assert 100 == ursula_wallet.call().calculateLockedTokens(8)
assert 0 == ursula_wallet.call().calculateLockedTokens(9)
assert 300 == ursula_wallet.call().calculateLockedTokens(7)
assert 0 == ursula_wallet.call().calculateLockedTokens(8)
tx = wallet_manager.transact({'from': ursula}).lock(100, 1)
chain.wait.for_receipt(tx)
assert 700 == ursula_wallet.call().getLockedTokens()
assert 700 == ursula_wallet.call().calculateLockedTokens(6)
assert 450 == ursula_wallet.call().calculateLockedTokens(8)
assert 200 == ursula_wallet.call().calculateLockedTokens(9)
assert 0 == ursula_wallet.call().calculateLockedTokens(10)
assert 350 == ursula_wallet.call().calculateLockedTokens(8)
assert 0 == ursula_wallet.call().calculateLockedTokens(9)
# Alice can withdraw all
# TODO complete method