laconicd/tests-solidity/suites/staking/test/transfers.js
Brett Sun c9639c3860
tests: add solidity test suites (#487)
* tests: add solidity test suite

* tests: remove require strings

* Update tests-solidity/init-test-node.sh

* Update tests-solidity/init-test-node.sh

Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>
2020-09-01 17:16:28 -04:00

144 lines
7.0 KiB
JavaScript

const { assertRevert } = require('@aragon/contract-helpers-test/assertThrow')
const { assertBn, bn, MAX_UINT64 } = require('@aragon/contract-helpers-test/numbers')
const { deploy } = require('./helpers/deploy')(artifacts)
const { approveAndStake, approveStakeAndLock } = require('./helpers/helpers')(artifacts)
const { DEFAULT_STAKE_AMOUNT, DEFAULT_LOCK_AMOUNT, EMPTY_DATA, ZERO_ADDRESS } = require('./helpers/constants')
const { STAKING_ERRORS } = require('./helpers/errors')
contract('Staking app, Transferring', ([owner, user1, user2]) => {
let staking, token, lockManager
beforeEach(async () => {
const deployment = await deploy(owner)
token = deployment.token
staking = deployment.staking
lockManager = deployment.lockManager
})
context('Transfers', async () => {
context('From stake', async () => {
const transfersFromStake = (transferType) => {
it('transfers', async () => {
//const initialTotalStake = await staking.totalStaked()
const transferAmount = DEFAULT_STAKE_AMOUNT.div(bn(2))
await approveAndStake({ staking, from: owner })
await staking[transferType](user1, transferAmount)
assertBn(await staking.unlockedBalanceOf(owner), DEFAULT_STAKE_AMOUNT.sub(transferAmount), "Owner balance should match")
const userStakedBalance = transferType == 'transfer' ? transferAmount : bn(0)
assertBn(await staking.unlockedBalanceOf(user1), userStakedBalance, "User 1 unlocked balance should match")
const userExternalBalance = transferType == 'transfer' ? bn(0) : transferAmount
assertBn(await token.balanceOf(user1), userExternalBalance, "User 1 external balance should match")
// total stake
const totalStaked = transferType == 'transfer' ? DEFAULT_STAKE_AMOUNT : DEFAULT_STAKE_AMOUNT.sub(transferAmount)
assertBn(await staking.totalStaked(), totalStaked, "Total stake should match")
})
it('fails transferring zero tokens', async () => {
await approveAndStake({ staking, from: owner })
await assertRevert(staking[transferType](user1, 0)/*, STAKING_ERRORS.ERROR_AMOUNT_ZERO*/)
})
it('fails transferring more than staked balance', async () => {
await approveAndStake({ staking, amount: DEFAULT_STAKE_AMOUNT, from: owner })
await assertRevert(staking[transferType](user1, DEFAULT_STAKE_AMOUNT.add(bn(1)))/*, STAKING_ERRORS.ERROR_NOT_ENOUGH_BALANCE*/)
})
it('fails transferring more than unlocked balance', async () => {
await approveStakeAndLock({ staking, manager: lockManager.address, from: owner })
await assertRevert(staking[transferType](user1, DEFAULT_STAKE_AMOUNT)/*, STAKING_ERRORS.ERROR_NOT_ENOUGH_BALANCE*/)
})
}
context('within Staking app', () => {
transfersFromStake('transfer')
})
context('to external balance (unstaked)', () => {
transfersFromStake('transferAndUnstake')
})
})
const transfersFromLock = (transferType) => {
it('transfers', async () => {
await approveStakeAndLock({ staking, manager: lockManager.address, from: owner })
const transferAmount = DEFAULT_LOCK_AMOUNT.div(bn(2))
await lockManager[transferType](staking.address, owner, user1, transferAmount)
assertBn(await staking.unlockedBalanceOf(owner), DEFAULT_STAKE_AMOUNT.sub(DEFAULT_LOCK_AMOUNT), "Owner balance should match")
const userUnlockedBalance = transferType == 'slash' ? transferAmount : bn(0)
assertBn(await staking.unlockedBalanceOf(user1), userUnlockedBalance, "User 1 unlocked balance should match")
const userExternalBalance = transferType == 'slash' ? bn(0) : transferAmount
assertBn(await token.balanceOf(user1), userExternalBalance, "User 1 external balance should match")
// total stake
const totalStaked = transferType == 'slash' ? DEFAULT_STAKE_AMOUNT : DEFAULT_STAKE_AMOUNT.sub(transferAmount)
assertBn(await staking.totalStaked(), totalStaked, "Total stake should match")
// check lock values
const { _amount: amount, _data: data } = await staking.getLock(owner, lockManager.address)
assertBn(amount, DEFAULT_LOCK_AMOUNT.sub(transferAmount), "locked amount should match")
})
it('transfers the whole lock amount', async () => {
await approveStakeAndLock({ staking, manager: lockManager.address, from: owner })
await lockManager[transferType](staking.address, owner, user1, DEFAULT_LOCK_AMOUNT)
assertBn(await staking.unlockedBalanceOf(owner), DEFAULT_STAKE_AMOUNT.sub(DEFAULT_LOCK_AMOUNT), "Owner balance should match")
const userUnlockedBalance = transferType == 'slash' ? DEFAULT_LOCK_AMOUNT : bn(0)
assertBn(await staking.unlockedBalanceOf(user1), userUnlockedBalance, "User 1 unlocked balance should match")
const userExternalBalance = transferType == 'slash' ? bn(0) : DEFAULT_LOCK_AMOUNT
assertBn(await token.balanceOf(user1), userExternalBalance, "User 1 external balance should match")
// total stake
const totalStaked = transferType == 'slash' ? DEFAULT_STAKE_AMOUNT : DEFAULT_STAKE_AMOUNT.sub(DEFAULT_LOCK_AMOUNT)
assertBn(await staking.totalStaked(), totalStaked, "Total stake should match")
// check lock values
const { _amount: amount, _data: data } = await staking.getLock(owner, lockManager.address)
assertBn(amount, bn(0), "locked amount should match")
})
it('fails transferring zero tokens', async () => {
await approveStakeAndLock({ staking, manager: lockManager.address, from: owner })
await assertRevert(lockManager[transferType](staking.address, owner, user1, 0)/*, STAKING_ERRORS.ERROR_AMOUNT_ZERO*/)
})
it('fails transferring more than locked balance', async () => {
await approveStakeAndLock({ staking, manager: lockManager.address, from: owner })
await assertRevert(lockManager[transferType](staking.address, owner, user1, DEFAULT_LOCK_AMOUNT.add(bn(1)))/*, STAKING_ERRORS.ERROR_NOT_ENOUGH_LOCK*/)
})
it('fails if sender is not manager', async () => {
await approveStakeAndLock({ staking, manager: user1, from: owner })
await assertRevert(lockManager[transferType](staking.address, owner, user1, DEFAULT_LOCK_AMOUNT)/*, STAKING_ERRORS.ERROR_NOT_ENOUGH_LOCK*/)
})
it('fails transferring from unlocked lock', async () => {
await approveStakeAndLock({ staking, manager: lockManager.address, from: owner })
// unlock
await lockManager.unlockAndRemoveManager(staking.address, owner)
await assertRevert(lockManager[transferType](staking.address, owner, user2, DEFAULT_LOCK_AMOUNT, { from: user1 })/*, STAKING_ERRORS.ERROR_NOT_ENOUGH_LOCK*/)
})
}
context('From Lock', async () => {
context('within Staking app', () => {
transfersFromLock('slash')
})
context('to external balance (unstaked)', () => {
transfersFromLock('slashAndUnstake')
})
})
})
})