From 73400ff3ac1d6e140a6634cbc491add8cc9cc396 Mon Sep 17 00:00:00 2001 From: Andy Tudhope Date: Mon, 8 Apr 2019 21:22:45 +0200 Subject: [PATCH] More tests, WIP --- contracts/DAppStore.sol | 25 +++++++++------ test/dappstore_spec.js | 71 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 10 deletions(-) diff --git a/contracts/DAppStore.sol b/contracts/DAppStore.sol index b057d43..340a6aa 100644 --- a/contracts/DAppStore.sol +++ b/contracts/DAppStore.sol @@ -175,29 +175,34 @@ contract DAppStore is ApproveAndCallFallBack, BancorFormula { uint balance_down_by = (d.effective_balance / 100); uint votes_required = (balance_down_by * d.votes_minted * d.rate) / d.available; - uint cost = (d.available / (d.votes_minted - (d.votes_cast + votes_required))) * (votes_required / 1 / 10000); + uint votes_available = d.votes_minted - d.votes_cast - votes_required; + uint temp = (d.available / votes_available) * (votes_required); + uint cost = temp / decimals; return (balance_down_by, votes_required, cost); } /** * @dev Sends SNT directly to the developer and lower the DApp's effective balance by 1% * @param _id bytes32 unique identifier. + * @param _amount uint, set back to actual cost, just included for approveAndCallFallBack */ - function downvote(bytes32 _id) public { - _downvote(msg.sender, _id); + function downvote(bytes32 _id, uint _amount) public { + (,,uint c) = downvoteCost(_id); + _amount == c; + _downvote(msg.sender, _id, c); } - function _downvote(address _from, bytes32 _id) internal { + function _downvote(address _from, bytes32 _id, uint _amount) internal { uint dappIdx = id2index[_id]; Data storage d = dapps[dappIdx]; require(d.id == _id, "Error fetching correct data"); - (uint b, uint v_r, uint c) = downvoteCost(_id); + (uint b, uint v_r,) = downvoteCost(_id); - require(SNT.allowance(_from, d.developer) >= c, "Not enough SNT allowance"); - require(SNT.transferFrom(_from, d.developer, c), "Transfer failed"); + require(SNT.allowance(_from, d.developer) >= _amount, "Not enough SNT allowance"); + require(SNT.transferFrom(_from, d.developer, _amount), "Transfer failed"); - d.available = d.available - c; + d.available = d.available - _amount; d.votes_cast = d.votes_cast + v_r; d.effective_balance = d.effective_balance - b; @@ -267,8 +272,8 @@ contract DAppStore is ApproveAndCallFallBack, BancorFormula { if(sig == bytes4(0x1a214f43)) { _createDApp(_from, id, amount); - } else if(sig == bytes4(0x466055f3)) { - _downvote(_from, id); + } else if(sig == bytes4(0xac769090)) { + _downvote(_from, id, amount); } else if(sig == bytes4(0x2b3df690)) { _upvote(_from, id, amount); } else { diff --git a/test/dappstore_spec.js b/test/dappstore_spec.js index 912d73d..7ba0bf3 100644 --- a/test/dappstore_spec.js +++ b/test/dappstore_spec.js @@ -81,4 +81,75 @@ contract("DAppStore", function () { assert.strictEqual(parseInt(receipt.votes_cast, 10), 0); assert.strictEqual(parseInt(receipt.effective_balance, 10), amount); }) + + it("should handle first upvote correctly", async function () { + let id = "0x7465737400000000000000000000000000000000000000000000000000000000"; + let amount = 100; + + let initial = await DAppStore.methods.dapps(0).call(); + + await SNT.methods.generateTokens(accounts[0], amount).send(); + const encodedCall = DAppStore.methods.upvote(id,amount).encodeABI(); + await SNT.methods.approveAndCall(DAppStore.options.address, amount, encodedCall).send({from: accounts[0]}); + + let receipt = await DAppStore.methods.dapps(0).call(); + + let developer = accounts[0]; + assert.strictEqual(receipt.developer, developer); + + assert.strictEqual(receipt.id, id); + + let upvotedBalance = parseInt(initial.balance, 10) + amount + assert.strictEqual(parseInt(receipt.balance, 10), upvotedBalance); + + let max = await DAppStore.methods.max().call(); + let decimals = await DAppStore.methods.decimals().call(); + let rate = Math.round(decimals - (upvotedBalance * decimals/max)); + assert.strictEqual(parseInt(receipt.rate, 10), rate); + + let available = upvotedBalance * rate; + assert.strictEqual(parseInt(receipt.available, 10), available); + + let votes_minted = Math.round((available/decimals) ** (decimals/rate)); + assert.strictEqual(parseInt(receipt.votes_minted, 10), votes_minted); + + assert.strictEqual(parseInt(receipt.votes_cast, 10), 0); + + assert.strictEqual(parseInt(receipt.effective_balance, 10), upvotedBalance); + }) + + it("should handle first downvote correctly", async function () { + let id = "0x7465737400000000000000000000000000000000000000000000000000000000"; + let cost = await DAppStore.methods.downvoteCost(id).call() + let amount = parseInt(cost.c, 10); + + let initial = await DAppStore.methods.dapps(0).call(); + + await SNT.methods.generateTokens(accounts[1], 10000).send(); + const encodedCall = DAppStore.methods.downvote(id,amount).encodeABI(); + console.log(initial.developer, amount); + await SNT.methods.approveAndCall(initial.developer, amount, encodedCall).send({from: accounts[1]}); + + let receipt = await DAppStore.methods.dapps(0).call(); + + let developer = accounts[0]; + assert.strictEqual(receipt.developer, developer); + + assert.strictEqual(receipt.id, id); + + // Balance, rate, and votes_minted remain unchanged for downvotes + assert.strictEqual(receipt.balance, initial.balance); + + assert.strictEqual(receipt.rate, initial.rate); + + assert.strictEqual(receipt.votes_minted, initial.votes_minted); + + let available = parseInt(initial.available, 10) - parseInt(cost.c, 10); + assert.strictEqual(parseInt(receipt.available, 10), available); + + assert.strictEqual(parseInt(receipt.votes_cast, 10), parseInt(cost.v_r, 10)); + + let e_balance = parseInt(initial.effective_balance, 10) - parseInt(cost.b, 10); + assert.strictEqual(parseInt(receipt.effective_balance, 10), e_balance); + }) });