Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Staking: Address PR #101 comments #351

Merged
merged 11 commits into from
Jun 7, 2018
Merged

Staking: Address PR #101 comments #351

merged 11 commits into from
Jun 7, 2018

Conversation

bingen
Copy link
Contributor

@bingen bingen commented Jun 1, 2018

And add tests.

TODO: fix issue with timeTravel and solidity coverage (it works fine with npm run test)

@coveralls
Copy link

coveralls commented Jun 1, 2018

Coverage Status

Coverage remained the same at 94.91% when pulling 7877e47 on staking_2 into 6514851 on staking.

@bingen bingen changed the title [WIP] Address PR #101 comments Staking: Address PR #101 comments Jun 5, 2018
@bingen bingen requested review from izqui and sohkai June 5, 2018 14:18
Copy link
Contributor

@izqui izqui left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initial review :) Good job with those tests, there is in general quite a bit of dupped logic, specially in the assertions that we could maybe move into functions.

@@ -97,6 +104,10 @@ contract Staking is ERCStaking, AragonApp {
}
}

function lockIndefinitely(uint256 amount, address unlocker, bytes32 metadata, bytes data) public returns(uint256 lockId) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason for adding a function for this? See a limited usecase and people can do it themselves anyway

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I thought it may be convenient for the user to avoid the need of uint8(TimeUnit.Seconds), MAX_UINT64, but I can remove it if you don't think so.

// process Stake
accounts[acct].amount = accounts[acct].amount.add(amount);

Staked(acct, amount, totalStakedFor(acct), data);

if (stakeScript.length > 0) {
runScript(stakeScript, data, new address[](0));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm having second thoughts on whether we should add stakingToken to the blacklist for all script executions

Lock memory newLock = Lock(amount, Timespan(lockEnds, TimeUnit(lockUnit)), unlocker, metadata);
uint256 lockId = accounts[msg.sender].locks.push(newLock) - 1;
lockId = accounts[msg.sender].locks.push(newLock) - 1;

Locked(msg.sender, lockId, metadata);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should log the amount of locked tokens

while (accounts[acct].locks.length > 0) {
if (canUnlock(acct, 0)) {
unlock(acct, 0);
uint256 lastAccountLock = accounts[acct].locks.length - 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea of this function, but we shouldn't re-implement unlock here. Why not just iterate over all as in unlockAll?

accounts[from].amount -= amount;
accounts[to].amount += amount;
// make sure we don't move locked tokens, to avoid inconsistency
require(unlockedBalanceOf(from) >= amount);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand where you are coming from, but I think move tokens should be able to move them regardless of locks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But the (correct me if I'm wrong) the following situation may happen: an account could have more locked tokens than staked. So that account could try to stake more tokens for whatever reason but still wouldn't have available staked tokens. Even more, unlockedBalanceOf could revert trying to do the subtraction. I think that leaving such an inconsistent state where locked tokens amount can be greater than staked amount can give a lot of problems and be very confusing for the user. Let me put it this way: how can you have locked tokens that you don't actually have?
Another option would be to allow moveTokens to unlock first, but then it should require UNLOCK_ROLE. Maybe we can do an unlockAndMove function.

// we just send dumb transactions to increment block number
let blockNumber
do {
await mockCounter.increment()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice hack 😂🙏 Though this is going to slow down the test unnecessarily. Two possible solutions:

Also rather than introducing a random contract, you can perform ETH value transfers to the same account web3.eth.sendTransaction({ from: owner, to: owner: value: 1, gasPrice: 1 }) to bump blocks.

do {
await mockCounter.increment()
blockNumber = await getBlockNumber()
} while( blockNumber <= initialBlockNumber + blocks)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also I hadn't seen this in a while 😉. We could just do a for (let x of new Array(blocks)) without the block number check, as ganache always creates a new block per tx submitted.

If we want these tests to properly run in geth or parity, we should await for the block to change before continuing sending txs

assert.equal((await app.locksCount(owner)).valueOf(), 1, "there shouldn't be locks")
})

it('fails trying to unlockAllOrNone', async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'fails to unlockAllOrNone if a lock cannot be unlocked'

return assertRevert(async () => {
await app.moveTokens(owner, other, amount + 1)
})
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a test for failing to move more tokens from an account than unlocked.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

assert.equal((await app.totalStakedFor(owner)).valueOf(), amount, "staked value should match")
assert.equal(await executionTarget.stakeCounter(), 1, 'should have received execution call')
})

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add test for stakeAndLock triggering both scripts

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@bingen bingen merged commit 99f507f into staking Jun 7, 2018
@bingen bingen mentioned this pull request Jun 7, 2018
@sohkai sohkai deleted the staking_2 branch June 11, 2018 10:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants