mirror of
https://github.com/dap-ps/discover.git
synced 2025-02-07 06:54:49 +00:00
* chore: update to Embark v5 * fix: fix tests for Embark 5 * update Embark version and remove Geth client * change contracts to deploy and add cross-env for Windows support * feat: upgrade to Embark 5.1.nightly2 Fixes the problem of not exiting on build end * update to Embark 5.1 Fixes issue where artifacts are not built
704 lines
31 KiB
JavaScript
704 lines
31 KiB
JavaScript
const TestUtils = require("../utils/testUtils");
|
|
const BN = require('bn.js');
|
|
const Discover = require('Embark/contracts/Discover');
|
|
const SNT = require('Embark/contracts/SNT');
|
|
|
|
config({
|
|
blockchain: {
|
|
accounts: [
|
|
{
|
|
mnemonic: 'foster gesture flock merge beach plate dish view friend leave drink valley shield list enemy',
|
|
balance: '5 ether',
|
|
numAddresses: '10',
|
|
},
|
|
],
|
|
},
|
|
contracts: {
|
|
deploy: {
|
|
'MiniMeToken': { 'deploy': false },
|
|
'MiniMeTokenFactory': {},
|
|
'SNT': {
|
|
'instanceOf': 'MiniMeToken',
|
|
'args': [
|
|
'$MiniMeTokenFactory',
|
|
'0x0000000000000000000000000000000000000000',
|
|
0,
|
|
'TestMiniMeToken',
|
|
18,
|
|
'SNT',
|
|
true,
|
|
],
|
|
},
|
|
'Discover': {
|
|
args: ['$SNT'],
|
|
},
|
|
'TestBancorFormula': {},
|
|
},
|
|
},
|
|
}, (_err, web3_accounts) => {
|
|
accounts = web3_accounts
|
|
});
|
|
|
|
contract("Discover", function () {
|
|
|
|
this.timeout(0);
|
|
|
|
let decimalMultiplier = new BN('1000000000000000000', 10)
|
|
|
|
it("should set max and safeMax values correctly", async function () {
|
|
let resultMax = await Discover.methods.max().call();
|
|
let resultSafeMax = await Discover.methods.safeMax().call();
|
|
let expectedMax = 6804870174 * 292 / 1000000;
|
|
let expectedSafeMax = expectedMax * 77 / 100 - 1;
|
|
assert.strictEqual(parseInt(resultMax, 10), Math.round(expectedMax));
|
|
assert.strictEqual(parseInt(resultSafeMax, 10), Math.round(expectedSafeMax));
|
|
});
|
|
|
|
it("should create a new DApp and initialise it correctly", async function () {
|
|
let id = "0x7465737400000000000000000000000000000000000000000000000000000000";
|
|
let tokens = 1000;
|
|
let tokenAmount = new BN(tokens, 10);
|
|
let temp = decimalMultiplier.mul(new BN(tokenAmount, 10));
|
|
let amount = temp.toString();
|
|
let metadata = "QmSmv5e5DYc2otwWcpUzuqmt389s3HHx651TbxDvKBFFue";
|
|
|
|
await SNT.methods.generateTokens(accounts[0], amount).send();
|
|
const encodedCall = Discover.methods.createDApp(id, amount, TestUtils.getBytes32FromIpfsHash(metadata)).encodeABI();
|
|
await SNT.methods.approveAndCall(Discover.options.address, amount, encodedCall).send({ from: accounts[0] });
|
|
|
|
let receipt = await Discover.methods.dapps(0).call();
|
|
let developer = accounts[0];
|
|
|
|
assert.strictEqual(developer, receipt.developer);
|
|
assert.strictEqual(id, receipt.id);
|
|
assert.strictEqual(metadata, TestUtils.getIpfsHashFromBytes32(receipt.metadata));
|
|
|
|
// Check Discover actually receives the SNT!
|
|
let bal_receipt = await SNT.methods.balanceOf(Discover.options.address).call();
|
|
assert.strictEqual(parseInt(amount, 10), parseInt(bal_receipt, 10));
|
|
|
|
// Having received the SNT, check that it updates the particular DApp's storage values
|
|
assert.strictEqual(tokens, parseInt(receipt.balance, 10));
|
|
|
|
let max = await Discover.methods.max().call();
|
|
let decimals = await Discover.methods.decimals().call();
|
|
let rate = Math.round(decimals - (tokens * decimals / max));
|
|
assert.strictEqual(rate, parseInt(receipt.rate, 10));
|
|
|
|
let available = tokens * rate;
|
|
assert.strictEqual(available, parseInt(receipt.available, 10));
|
|
|
|
let votes_minted = Math.floor((available / decimals) ** (decimals / rate));
|
|
assert.strictEqual(votes_minted, parseInt(receipt.votesMinted, 10));
|
|
|
|
assert.strictEqual(0, parseInt(receipt.votesCast, 10));
|
|
assert.strictEqual(tokens, parseInt(receipt.effectiveBalance, 10));
|
|
})
|
|
|
|
it("should not create a new DApp with the same ID", async function () {
|
|
let id = "0x7465737400000000000000000000000000000000000000000000000000000000";
|
|
let tokenAmount = new BN(1000, 10);
|
|
let temp = decimalMultiplier.mul(new BN(tokenAmount, 10));
|
|
let amount = temp.toString();
|
|
let metadata = 'QmSmv5e5DYc2otwWcpUzuqmt389s3HHx651TbxDvKBFFue';
|
|
|
|
await SNT.methods.generateTokens(accounts[0], amount).send();
|
|
const encodedCall = Discover.methods.createDApp(id, amount, TestUtils.getBytes32FromIpfsHash(metadata)).encodeABI();
|
|
|
|
try {
|
|
await SNT.methods.approveAndCall(Discover.options.address, amount, encodedCall).send({ from: accounts[0] });
|
|
assert.fail('should have reverted before');
|
|
} catch (error) {
|
|
TestUtils.assertJump(error);
|
|
}
|
|
})
|
|
|
|
it("should not create a new DApp when exceeding the ceiling or staking nothing", async function () {
|
|
let id = "0x7465737400000000000000000000000000000000000000000000000000000000";
|
|
let metadata = 'QmSmv5e5DYc2otwWcpUzuqmt389s3HHx651TbxDvKBFFue';
|
|
let initial = await Discover.methods.max().call();
|
|
let tokens = parseInt(initial, 10);
|
|
let tokenAmount = new BN(tokens, 10);
|
|
let temp = decimalMultiplier.mul(new BN(tokenAmount, 10));
|
|
let amount = temp.toString();
|
|
let amount0 = 0;
|
|
|
|
await SNT.methods.generateTokens(accounts[0], amount).send();
|
|
|
|
const encodedCall = Discover.methods.createDApp(id, amount, TestUtils.getBytes32FromIpfsHash(metadata)).encodeABI();
|
|
try {
|
|
await SNT.methods.approveAndCall(Discover.options.address, amount, encodedCall).send({ from: accounts[0] });
|
|
assert.fail('should have reverted before');
|
|
} catch (error) {
|
|
TestUtils.assertJump(error);
|
|
}
|
|
|
|
const encodedCall0 = Discover.methods.createDApp(id, amount0, TestUtils.getBytes32FromIpfsHash(metadata)).encodeABI();
|
|
try {
|
|
await SNT.methods.approveAndCall(Discover.options.address, amount0, encodedCall0).send({ from: accounts[0] });
|
|
assert.fail('should have reverted before');
|
|
} catch (error) {
|
|
TestUtils.assertJump(error);
|
|
}
|
|
})
|
|
|
|
it("should update the metadata correctly", async function () {
|
|
let id = "0x7465737400000000000000000000000000000000000000000000000000000000";
|
|
let metadata = "QmSmv5e5DYc2otwWcpUzuqmt389s3HHx651TbxDvKBFFeu";
|
|
await Discover.methods.setMetadata(id, TestUtils.getBytes32FromIpfsHash(metadata)).send({ from: accounts[0] });
|
|
let receipt = await Discover.methods.dapps(0).call();
|
|
assert.strictEqual(TestUtils.getBytes32FromIpfsHash(metadata), receipt.metadata);
|
|
})
|
|
|
|
it("should not let anyone other than the developer update the metadata", async function () {
|
|
let id = "0x7465737400000000000000000000000000000000000000000000000000000000";
|
|
let metadata_actual = "QmSmv5e5DYc2otwWcpUzuqmt389s3HHx651TbxDvKBFFeu";
|
|
let metadata = "QmSmv5e5DYc2otwWcpUzuqmt389s3HHx651TbxDvKBDDeu";
|
|
try {
|
|
await Discover.methods.setMetadata(id, TestUtils.getBytes32FromIpfsHash(metadata)).send({ from: accounts[1] });
|
|
assert.fail('should have reverted before');
|
|
} catch (error) {
|
|
TestUtils.assertJump(error);
|
|
}
|
|
let receipt = await Discover.methods.dapps(0).call();
|
|
assert.strictEqual(TestUtils.getBytes32FromIpfsHash(metadata_actual), receipt.metadata);
|
|
})
|
|
|
|
it("should handle first upvote correctly", async function () {
|
|
let id = "0x7465737400000000000000000000000000000000000000000000000000000000";
|
|
let tokens = 100;
|
|
let tokenAmount = new BN(tokens, 10);
|
|
let temp = decimalMultiplier.mul(new BN(tokenAmount, 10));
|
|
let amount = temp.toString();
|
|
|
|
let initial = await Discover.methods.dapps(0).call();
|
|
let before = await SNT.methods.balanceOf(Discover.options.address).call();
|
|
// This is the special case where no downvotes have yet been cast
|
|
let up_effect = await Discover.methods.upvoteEffect(id, tokens).call();
|
|
|
|
await SNT.methods.generateTokens(accounts[0], amount).send();
|
|
const encodedCall = Discover.methods.upvote(id, amount).encodeABI();
|
|
await SNT.methods.approveAndCall(Discover.options.address, amount, encodedCall).send({ from: accounts[0] });
|
|
|
|
let receipt = await Discover.methods.dapps(0).call();
|
|
|
|
let developer = accounts[0];
|
|
|
|
assert.strictEqual(developer, receipt.developer);
|
|
assert.strictEqual(id, receipt.id);
|
|
|
|
// Check Discover actually receives the SNT!
|
|
let after = await SNT.methods.balanceOf(Discover.options.address).call();
|
|
let bal_effect = parseInt(after, 10) - parseInt(before, 10);
|
|
assert.strictEqual(bal_effect, parseInt(amount, 10));
|
|
|
|
// Having received the SNT, check that it updates the particular DApp's storage values
|
|
let upvotedBalance = parseInt(initial.balance, 10) + tokens;
|
|
assert.strictEqual(upvotedBalance, parseInt(receipt.balance, 10));
|
|
|
|
let max = await Discover.methods.max().call();
|
|
let decimals = await Discover.methods.decimals().call();
|
|
let rate = Math.ceil(decimals - (upvotedBalance * decimals / max));
|
|
assert.strictEqual(rate, parseInt(receipt.rate, 10));
|
|
|
|
let available = upvotedBalance * rate;
|
|
assert.strictEqual(available, parseInt(receipt.available, 10));
|
|
|
|
let votes_minted = Math.floor((available / decimals) ** (decimals / rate));
|
|
assert.strictEqual(votes_minted, parseInt(receipt.votesMinted, 10));
|
|
|
|
// Only true for upvotes made when there are no downvotes
|
|
assert.strictEqual(0, parseInt(receipt.votesCast, 10));
|
|
|
|
// The effective_balance should match upvoteEffect + initial.effectiveBalance
|
|
let e_balance = parseInt(up_effect, 10) + parseInt(initial.effectiveBalance, 10);
|
|
assert.strictEqual(e_balance, parseInt(receipt.effectiveBalance, 10));
|
|
})
|
|
|
|
it("should not let you upvote without spending SNT", async function () {
|
|
let id = "0x7465737400000000000000000000000000000000000000000000000000000000";
|
|
let amount = 0;
|
|
|
|
await SNT.methods.generateTokens(accounts[0], 10000).send();
|
|
const encodedCall = Discover.methods.upvote(id, amount).encodeABI();
|
|
try {
|
|
await SNT.methods.approveAndCall(Discover.options.address, amount, encodedCall).send({ from: accounts[0] });
|
|
assert.fail('should have reverted before');
|
|
} catch (error) {
|
|
TestUtils.assertJump(error);
|
|
}
|
|
})
|
|
|
|
it("should not let you upvote by an amount that exceeds the ceiling", async function () {
|
|
let id = "0x7465737400000000000000000000000000000000000000000000000000000000";
|
|
let initial = await Discover.methods.max().call();
|
|
let tokens = parseInt(initial, 10);
|
|
let tokenAmount = new BN(tokens, 10);
|
|
let temp = decimalMultiplier.mul(new BN(tokenAmount, 10));
|
|
let amount = temp.toString();
|
|
|
|
await SNT.methods.generateTokens(accounts[0], amount).send();
|
|
const encodedCall = Discover.methods.upvote(id, amount).encodeABI();
|
|
try {
|
|
await SNT.methods.approveAndCall(Discover.options.address, amount, encodedCall).send({ from: accounts[0] });
|
|
assert.fail('should have reverted before');
|
|
} catch (error) {
|
|
TestUtils.assertJump(error);
|
|
}
|
|
})
|
|
|
|
it("should handle first downvote correctly", async function () {
|
|
let id = "0x7465737400000000000000000000000000000000000000000000000000000000";
|
|
let cost = await Discover.methods.downvoteCost(id).call()
|
|
let tokens = parseInt(cost.c, 10);
|
|
let tokenAmount = new BN(tokens, 10);
|
|
let temp = decimalMultiplier.mul(new BN(tokenAmount, 10));
|
|
let amount = temp.toString();
|
|
|
|
let developer = accounts[0];
|
|
let initial = await Discover.methods.dapps(0).call();
|
|
let bal_before = await SNT.methods.balanceOf(developer).call();
|
|
|
|
await SNT.methods.generateTokens(accounts[1], amount).send();
|
|
const encodedCall = Discover.methods.downvote(id, amount).encodeABI();
|
|
await SNT.methods.approveAndCall(Discover.options.address, amount, encodedCall).send({ from: accounts[1] });
|
|
|
|
let receipt = await Discover.methods.dapps(0).call();
|
|
|
|
assert.strictEqual(developer, receipt.developer);
|
|
assert.strictEqual(id, receipt.id);
|
|
|
|
// Check the developer actually receives the SNT!
|
|
let bal_after = await SNT.methods.balanceOf(developer).call();
|
|
let bal_effect = parseInt(bal_after, 10) - parseInt(bal_before, 10)
|
|
assert.strictEqual(Math.round(bal_effect/decimalMultiplier), tokens);
|
|
|
|
// Balance, rate, and votes_minted remain unchanged for downvotes
|
|
assert.strictEqual(initial.balance, receipt.balance);
|
|
assert.strictEqual(initial.rate, receipt.rate);
|
|
assert.strictEqual(initial.votesMinted, receipt.votesMinted);
|
|
|
|
let available = parseInt(initial.available, 10) - parseInt(cost.c, 10);
|
|
assert.strictEqual(available, parseInt(receipt.available, 10));
|
|
|
|
// This is only true for the first downvote
|
|
assert.strictEqual(parseInt(receipt.votesCast, 10), parseInt(cost.vR, 10));
|
|
|
|
let e_balance = parseInt(initial.effectiveBalance, 10) - parseInt(cost.b, 10);
|
|
assert.strictEqual(e_balance, parseInt(receipt.effectiveBalance, 10));
|
|
})
|
|
|
|
it("should handle second downvote correctly", async function () {
|
|
let id = "0x7465737400000000000000000000000000000000000000000000000000000000";
|
|
let cost = await Discover.methods.downvoteCost(id).call()
|
|
let tokens = parseInt(cost.c, 10);
|
|
let tokenAmount = new BN(tokens, 10);
|
|
let temp = decimalMultiplier.mul(new BN(tokenAmount, 10));
|
|
let amount = temp.toString();
|
|
let developer = accounts[0];
|
|
|
|
let initial = await Discover.methods.dapps(0).call();
|
|
let bal_before = await SNT.methods.balanceOf(developer).call();
|
|
|
|
await SNT.methods.generateTokens(accounts[1], amount).send();
|
|
const encodedCall = Discover.methods.downvote(id, amount).encodeABI();
|
|
await SNT.methods.approveAndCall(Discover.options.address, amount, encodedCall).send({ from: accounts[1] });
|
|
|
|
let receipt = await Discover.methods.dapps(0).call();
|
|
|
|
assert.strictEqual(developer, receipt.developer);
|
|
assert.strictEqual(id, receipt.id);
|
|
|
|
// Check the developer actually receives the SNT!
|
|
let bal_after = await SNT.methods.balanceOf(developer).call();
|
|
let bal_effect = parseInt(bal_after, 10) - parseInt(bal_before, 10)
|
|
assert.strictEqual(Math.round(bal_effect/decimalMultiplier), tokens);
|
|
|
|
// Balance, rate, and votes_minted remain unchanged for downvotes
|
|
assert.strictEqual(initial.balance, receipt.balance);
|
|
assert.strictEqual(initial.rate, receipt.rate);
|
|
assert.strictEqual(initial.votesMinted, receipt.votesMinted);
|
|
|
|
let available = parseInt(initial.available, 10) - parseInt(cost.c, 10);
|
|
assert.strictEqual(available, parseInt(receipt.available, 10));
|
|
|
|
let eff_v_cast = parseInt(receipt.votesCast, 10) - parseInt(initial.votesCast, 10);
|
|
assert.strictEqual(eff_v_cast, parseInt(cost.vR, 10));
|
|
|
|
let e_balance = parseInt(initial.effectiveBalance, 10) - parseInt(cost.b, 10);
|
|
assert.strictEqual(e_balance, parseInt(receipt.effectiveBalance, 10));
|
|
})
|
|
|
|
it("should not let you downvote by the wrong amount", async function () {
|
|
let id = "0x7465737400000000000000000000000000000000000000000000000000000000";
|
|
let tokensAbove = 100000;
|
|
let tokensBelow = 25;
|
|
let tokenAboveAmount = new BN(tokensAbove, 10);
|
|
let tokenBelowAmount = new BN(tokensBelow, 10);
|
|
let temp1 = decimalMultiplier.mul(new BN(tokenAboveAmount, 10));
|
|
let temp2 = decimalMultiplier.mul(new BN(tokenBelowAmount, 10))
|
|
let amountAbove = temp1.toString();
|
|
let amountBelow = temp2.toString();
|
|
|
|
await SNT.methods.generateTokens(accounts[1], amountAbove + amountBelow).send();
|
|
const encodedCall = Discover.methods.downvote(id, amountAbove).encodeABI();
|
|
try {
|
|
await SNT.methods.approveAndCall(Discover.options.address, amountAbove, encodedCall).send({ from: accounts[1] });
|
|
assert.fail('should have reverted before');
|
|
} catch (error) {
|
|
TestUtils.assertJump(error);
|
|
}
|
|
|
|
const encodedCall1 = Discover.methods.downvote(id, amountBelow).encodeABI();
|
|
try {
|
|
await SNT.methods.approveAndCall(Discover.options.address, amountBelow, encodedCall1).send({ from: accounts[1] });
|
|
assert.fail('should have reverted before');
|
|
} catch (error) {
|
|
TestUtils.assertJump(error);
|
|
}
|
|
})
|
|
|
|
it("should handle upvotes correctly when votes have been cast", async function () {
|
|
let id = "0x7465737400000000000000000000000000000000000000000000000000000000";
|
|
let tokens = 500;
|
|
let tokenAmount = new BN(tokens, 10);
|
|
let temp = decimalMultiplier.mul(new BN(tokenAmount, 10));
|
|
let amount = temp.toString();
|
|
|
|
let initial = await Discover.methods.dapps(0).call();
|
|
let before = await SNT.methods.balanceOf(Discover.options.address).call();
|
|
let up_effect = await Discover.methods.upvoteEffect(id, tokens).call();
|
|
|
|
await SNT.methods.generateTokens(accounts[0], amount).send();
|
|
const encodedCall = Discover.methods.upvote(id, amount).encodeABI();
|
|
await SNT.methods.approveAndCall(Discover.options.address, amount, encodedCall).send({ from: accounts[0] });
|
|
|
|
let receipt = await Discover.methods.dapps(0).call();
|
|
let developer = accounts[0];
|
|
|
|
assert.strictEqual(developer, receipt.developer);
|
|
assert.strictEqual(id, receipt.id);
|
|
|
|
// Check Discover actually receives the SNT!
|
|
let after = await SNT.methods.balanceOf(Discover.options.address).call();
|
|
let bal_effect = parseInt(after, 10) - parseInt(before, 10);
|
|
assert.strictEqual(Math.round(bal_effect/decimalMultiplier), tokens);
|
|
|
|
// Having received the SNT, check that it updates the particular DApp's storage values
|
|
let upvotedBalance = parseInt(initial.balance, 10) + tokens
|
|
assert.strictEqual(upvotedBalance, parseInt(receipt.balance, 10));
|
|
|
|
let max = await Discover.methods.max().call();
|
|
let decimals = await Discover.methods.decimals().call();
|
|
let rate = Math.round(decimals - (upvotedBalance * decimals / max));
|
|
assert.strictEqual(rate, parseInt(receipt.rate, 10));
|
|
|
|
let available = upvotedBalance * rate;
|
|
assert.strictEqual(available, parseInt(receipt.available, 10));
|
|
|
|
let votes_minted = parseInt(receipt.votesMinted, 10);
|
|
|
|
// Votes have been cast by this stage, so we need to check how many there are
|
|
// and confirm that `upvote` still calculates the effective_balance correctly
|
|
let votes_cast = parseInt(receipt.votesCast, 10);
|
|
|
|
let e_balance = Math.ceil(upvotedBalance - ((votes_cast * rate / decimals) * (available / decimals / votes_minted)));
|
|
assert.strictEqual(e_balance, parseInt(receipt.effectiveBalance, 10));
|
|
|
|
// The effective_balance should also match upvoteEffect + initial.effectiveBalance
|
|
let e_balance_2 = parseInt(up_effect, 10) + parseInt(initial.effectiveBalance, 10);
|
|
assert.strictEqual(e_balance_2, parseInt(receipt.effectiveBalance, 10));
|
|
})
|
|
|
|
it("should return correct upvoteEffect for use in UI", async function () {
|
|
let id = "0x7465737400000000000000000000000000000000000000000000000000000000";
|
|
let amount = 10;
|
|
|
|
let receipt = await Discover.methods.dapps(0).call();
|
|
let effect = await Discover.methods.upvoteEffect(id, amount).call();
|
|
|
|
// Mock receiving the SNT
|
|
let mBalance = parseInt(receipt.balance, 10) + amount
|
|
|
|
let max = await Discover.methods.max().call();
|
|
let decimals = await Discover.methods.decimals().call();
|
|
|
|
let mRate = Math.round(decimals - (mBalance * decimals / max));
|
|
let mAvailable = mBalance * mRate;
|
|
let mVMinted = Math.round((mAvailable / decimals) ** (decimals / mRate));
|
|
|
|
// Votes have been cast by this stage, so we need to check how many there are
|
|
// and confirm that `upvoteEffect` mocks the effect correctly
|
|
let votes_cast = parseInt(receipt.votesCast, 10);
|
|
let mEBalance = Math.ceil(mBalance - ((votes_cast * mRate / decimals) * (mAvailable / decimals / mVMinted)));
|
|
let effect_calc = mEBalance - receipt.effectiveBalance;
|
|
|
|
// Confirm that what is returned is (mEBalance - d.effective_balance)
|
|
assert.strictEqual(effect_calc, parseInt(effect, 10));
|
|
})
|
|
|
|
it("should throw already in upvoteEffect if you exceed the ceiling", async function () {
|
|
let id = "0x7465737400000000000000000000000000000000000000000000000000000000";
|
|
let initial = await Discover.methods.max().call();
|
|
let amount = parseInt(initial, 10);
|
|
try {
|
|
await Discover.methods.upvoteEffect(id, amount).call();
|
|
assert.fail('should have reverted before');
|
|
} catch (error) {
|
|
TestUtils.assertJump(error);
|
|
}
|
|
})
|
|
|
|
it("should handle withdrawals correctly", async function () {
|
|
let id = "0x7465737400000000000000000000000000000000000000000000000000000000";
|
|
let tokens = 100;
|
|
let tokenAmount = new BN(tokens, 10);
|
|
let temp = decimalMultiplier.mul(new BN(tokenAmount, 10));
|
|
let amount = temp.toString();
|
|
|
|
let initial = await Discover.methods.dapps(0).call();
|
|
let before = await SNT.methods.balanceOf(Discover.options.address).call();
|
|
let before_dev = await SNT.methods.balanceOf(accounts[0]).call();
|
|
let receipt_obj = await Discover.methods.withdraw(id, amount).send({ from: accounts[0] });
|
|
let receipt = receipt_obj.events.Withdraw.returnValues;
|
|
|
|
assert.strictEqual(id, receipt.id);
|
|
|
|
// Check Discover actually sends SNT to the developer
|
|
let after = await SNT.methods.balanceOf(Discover.options.address).call();
|
|
let after_dev = await SNT.methods.balanceOf(accounts[0]).call();
|
|
let difference = parseInt(before, 10) - parseInt(after, 10);
|
|
let difference_dev = parseInt(after_dev, 10) - parseInt(before_dev, 10);
|
|
|
|
assert.strictEqual(Math.round(difference/decimalMultiplier), tokens)
|
|
assert.strictEqual(Math.round(difference_dev/decimalMultiplier), tokens)
|
|
|
|
// Recalculate e_balance manually and check it matches what is returned
|
|
let max = await Discover.methods.max().call();
|
|
let decimals = await Discover.methods.decimals().call();
|
|
|
|
let balance = parseInt(initial.balance, 10) - tokens
|
|
let rate = Math.ceil(decimals - (balance * decimals / max));
|
|
let available = Math.round(balance * rate);
|
|
let v_minted = Math.round((available / decimals) ** (decimals / rate));
|
|
let v_cast = parseInt(initial.votesCast, 10);
|
|
let e_balance = Math.ceil(balance - ((v_cast * rate / decimals) * (available / decimals / v_minted)));
|
|
|
|
let effective_balance = parseInt(receipt.newEffectiveBalance, 10);
|
|
|
|
// We begin to run into precision limitations in the BancorFormula here.
|
|
// The higher the amount, the less accurate it becomes. Hence Math.ceil() for now.
|
|
assert.strictEqual(e_balance, effective_balance);
|
|
|
|
// Having withdrawn the SNT, check that it updates the particular DApp's storage values properly
|
|
let check = await Discover.methods.dapps(0).call();
|
|
|
|
let withdrawnBalance = parseInt(initial.balance, 10) - tokens;
|
|
assert.strictEqual(parseInt(check.balance, 10), withdrawnBalance);
|
|
|
|
assert.strictEqual(parseInt(check.rate, 10), rate);
|
|
assert.strictEqual(parseInt(check.available, 10), available);
|
|
assert.strictEqual(parseInt(check.votesMinted, 10), v_minted);
|
|
})
|
|
|
|
it("should not allow withdrawing more than was staked", async function () {
|
|
let id = "0x7465737400000000000000000000000000000000000000000000000000000000";
|
|
let tokens = 150000;
|
|
let tokenAmount = new BN(tokens, 10);
|
|
let temp = decimalMultiplier.mul(new BN(tokenAmount, 10));
|
|
let amount = temp.toString();
|
|
try {
|
|
await Discover.methods.withdraw(id, amount).send({ from: accounts[0] });
|
|
assert.fail('should have reverted before');
|
|
} catch (error) {
|
|
TestUtils.assertJump(error);
|
|
}
|
|
})
|
|
|
|
it("should not allow withdrawing more than was staked minus what has already been received", async function () {
|
|
let id = "0x7465737400000000000000000000000000000000000000000000000000000000";
|
|
let receipt = await Discover.methods.dapps(0).call();
|
|
let tokens = parseInt(receipt.available, 10) + 1;
|
|
let tokenAmount = new BN(tokens, 10);
|
|
let temp = decimalMultiplier.mul(new BN(tokenAmount, 10));
|
|
let amount = temp.toString();
|
|
try {
|
|
await Discover.methods.withdraw(id, amount).send({ from: accounts[0] });
|
|
assert.fail('should have reverted before');
|
|
} catch (error) {
|
|
TestUtils.assertJump(error);
|
|
}
|
|
})
|
|
|
|
it("should not allow anyone other than the developer to withdraw", async function () {
|
|
let id = "0x7465737400000000000000000000000000000000000000000000000000000000";
|
|
let tokens = 1000;
|
|
let tokenAmount = new BN(tokens, 10);
|
|
let temp = decimalMultiplier.mul(new BN(tokenAmount, 10));
|
|
let amount = temp.toString();
|
|
try {
|
|
await Discover.methods.withdraw(id, amount).send({ from: accounts[1] });
|
|
} catch (error) {
|
|
TestUtils.assertJump(error);
|
|
}
|
|
})
|
|
|
|
it("should handle downvotes after withdrawals correctly", async function () {
|
|
let id = "0x7465737400000000000000000000000000000000000000000000000000000000";
|
|
let cost = await Discover.methods.downvoteCost(id).call()
|
|
let tokens = parseInt(cost.c, 10);
|
|
let tokenAmount = new BN(tokens, 10);
|
|
let temp = decimalMultiplier.mul(new BN(tokenAmount, 10));
|
|
let amount = temp.toString();
|
|
let developer = accounts[0];
|
|
|
|
let initial = await Discover.methods.dapps(0).call();
|
|
let bal_before = await SNT.methods.balanceOf(developer).call();
|
|
|
|
await SNT.methods.generateTokens(accounts[1], amount).send();
|
|
const encodedCall = Discover.methods.downvote(id, amount).encodeABI();
|
|
await SNT.methods.approveAndCall(Discover.options.address, amount, encodedCall).send({ from: accounts[1] });
|
|
|
|
let receipt = await Discover.methods.dapps(0).call();
|
|
|
|
assert.strictEqual(developer, receipt.developer);
|
|
assert.strictEqual(id, receipt.id);
|
|
|
|
// Check the developer actually receives the SNT!
|
|
let bal_after = await SNT.methods.balanceOf(developer).call();
|
|
let bal_effect = parseInt(bal_after, 10) - parseInt(bal_before, 10)
|
|
assert.strictEqual(Math.round(bal_effect/decimalMultiplier), tokens);
|
|
|
|
// Balance, rate, and votes_minted remain unchanged for downvotes
|
|
assert.strictEqual(initial.balance, receipt.balance);
|
|
assert.strictEqual(initial.rate, receipt.rate);
|
|
assert.strictEqual(initial.votesMinted, receipt.votesMinted);
|
|
|
|
let available = parseInt(initial.available, 10) - parseInt(cost.c, 10);
|
|
assert.strictEqual(available, parseInt(receipt.available, 10));
|
|
|
|
let eff_v_cast = parseInt(receipt.votesCast, 10) - parseInt(initial.votesCast, 10);
|
|
assert.strictEqual(eff_v_cast, parseInt(cost.vR, 10));
|
|
|
|
let e_balance = parseInt(initial.effectiveBalance, 10) - parseInt(cost.b, 10);
|
|
assert.strictEqual(e_balance, parseInt(receipt.effectiveBalance, 10));
|
|
})
|
|
|
|
it("should handle upvotes after withdrawals correctly", async function () {
|
|
let id = "0x7465737400000000000000000000000000000000000000000000000000000000";
|
|
let tokens = 100;
|
|
let tokenAmount = new BN(tokens, 10);
|
|
let temp = decimalMultiplier.mul(new BN(tokenAmount, 10));
|
|
let amount = temp.toString();
|
|
|
|
let initial = await Discover.methods.dapps(0).call();
|
|
let before = await SNT.methods.balanceOf(Discover.options.address).call();
|
|
let up_effect = await Discover.methods.upvoteEffect(id, tokens).call();
|
|
|
|
await SNT.methods.generateTokens(accounts[0], amount).send();
|
|
const encodedCall = Discover.methods.upvote(id, amount).encodeABI();
|
|
await SNT.methods.approveAndCall(Discover.options.address, amount, encodedCall).send({ from: accounts[0] });
|
|
|
|
let receipt = await Discover.methods.dapps(0).call();
|
|
let developer = accounts[0];
|
|
|
|
assert.strictEqual(developer, receipt.developer);
|
|
assert.strictEqual(id, receipt.id);
|
|
|
|
// Check Discover actually receives the SNT!
|
|
let after = await SNT.methods.balanceOf(Discover.options.address).call();
|
|
let bal_effect = parseInt(after, 10) - parseInt(before, 10);
|
|
assert.strictEqual(Math.round(bal_effect/decimalMultiplier), tokens);
|
|
|
|
// Having received the SNT, check that it updates the particular DApp's storage values
|
|
let upvotedBalance = parseInt(initial.balance, 10) + tokens
|
|
assert.strictEqual(upvotedBalance, parseInt(receipt.balance, 10));
|
|
|
|
let max = await Discover.methods.max().call();
|
|
let decimals = await Discover.methods.decimals().call();
|
|
let rate = Math.round(decimals - (upvotedBalance * decimals / max));
|
|
assert.strictEqual(rate, parseInt(receipt.rate, 10));
|
|
|
|
let available = upvotedBalance * rate;
|
|
assert.strictEqual(available, parseInt(receipt.available, 10));
|
|
|
|
let votes_minted = parseInt(receipt.votesMinted, 10);
|
|
|
|
// Votes have been cast by this stage, so we need to check how many there are
|
|
// and confirm that `upvote` still calculates the effective_balance correctly
|
|
let votes_cast = parseInt(receipt.votesCast, 10);
|
|
|
|
let e_balance = Math.ceil(upvotedBalance - ((votes_cast * rate / decimals) * (available / decimals / votes_minted)));
|
|
assert.strictEqual(e_balance, parseInt(receipt.effectiveBalance, 10));
|
|
|
|
// The effective_balance should also match upvoteEffect + initial.effectiveBalance
|
|
let e_balance_2 = parseInt(up_effect, 10) + parseInt(initial.effectiveBalance, 10);
|
|
assert.strictEqual(e_balance_2, parseInt(receipt.effectiveBalance, 10));
|
|
})
|
|
|
|
it("should create a DApp without overflowing", async function () {
|
|
let id = "0x0000000000000000000000000000000000000000000000000000000000000001";
|
|
let safeMax = await Discover.methods.safeMax().call();
|
|
let tokens = parseInt(safeMax, 10);
|
|
let tokenAmount = new BN(tokens, 10);
|
|
let temp = decimalMultiplier.mul(new BN(tokenAmount, 10));
|
|
let amount = temp.toString();
|
|
let metadata = "QmSmv5e5DYc2otwWcpUzuqmt389s3HHx651TbxDvKBFFue";
|
|
|
|
await SNT.methods.generateTokens(accounts[0], amount).send();
|
|
const encodedCall = Discover.methods.createDApp(id, amount, TestUtils.getBytes32FromIpfsHash(metadata)).encodeABI();
|
|
await SNT.methods.approveAndCall(Discover.options.address, amount, encodedCall).send({ from: accounts[0] });
|
|
|
|
let receipt = await Discover.methods.dapps(1).call();
|
|
let developer = accounts[0];
|
|
|
|
assert.strictEqual(developer, receipt.developer);
|
|
assert.strictEqual(id, receipt.id);
|
|
|
|
// Having received the SNT, check that it updates the particular DApp's storage values
|
|
assert.strictEqual(tokens, parseInt(receipt.balance, 10));
|
|
|
|
let max = await Discover.methods.max().call();
|
|
let decimals = await Discover.methods.decimals().call();
|
|
let rate = Math.ceil(decimals - (tokens * decimals / max));
|
|
assert.strictEqual(rate, parseInt(receipt.rate, 10));
|
|
|
|
let available = tokens * rate;
|
|
assert.strictEqual(available, parseInt(receipt.available, 10));
|
|
|
|
// It's checking that votesMinted doesn't overflow which we're really interested in here
|
|
let votes_minted = Math.round((available / decimals) ** (decimals / rate));
|
|
let returned = parseInt(receipt.votesMinted, 10);
|
|
|
|
// Is going to be less than due to rounding inaccuracies at higher exponents
|
|
assert.ok(returned <= votes_minted);
|
|
})
|
|
|
|
// Comment out line 263 in the contract to run this test properly and see
|
|
// the BancorFormula fail to find a suitable position in the maxExponentArray
|
|
it("should prove we have the highest safeMax allowed for by Bancor's power approximation", async function () {
|
|
let id = "0x0000000000000000000000000000000000000000000000000000000000000002";
|
|
let max = await Discover.methods.max().call();
|
|
// Choose a safeMax 1% higher than is currently set
|
|
let percent = 78 / 100;
|
|
let tokens = Math.round(parseInt(max, 10) * percent);
|
|
let tokenAmount = new BN(tokens, 10);
|
|
let temp = decimalMultiplier.mul(new BN(tokenAmount, 10));
|
|
let amount = temp.toString();
|
|
let metadata = "QmSmv5e5DYc2otwWcpUzuqmt389s3HHx651TbxDvKBFFue";
|
|
|
|
await SNT.methods.generateTokens(accounts[0], amount).send();
|
|
const encodedCall = Discover.methods.createDApp(id, amount, TestUtils.getBytes32FromIpfsHash(metadata)).encodeABI();
|
|
|
|
// Comment this try/catch block out to test the safeMax
|
|
try {
|
|
await SNT.methods.approveAndCall(Discover.options.address, amount, encodedCall).send({ from: accounts[0] });
|
|
} catch (error) {
|
|
TestUtils.assertJump(error);
|
|
}
|
|
|
|
// Uncomment the next line to check this test. Change percent to 77 or 76 to see it pass.
|
|
// await SNT.methods.approveAndCall(Discover.options.address, amount, encodedCall).send({ from: accounts[0] });
|
|
})
|
|
});
|