mirror of
https://github.com/status-im/discover-dapps.git
synced 2025-02-02 13:53:49 +00:00
Adds overflow test and better protection given limitations
This commit is contained in:
parent
2889281dbb
commit
afc8adb22c
@ -44,7 +44,7 @@ contract DAppStore is ApproveAndCallFallBack, BancorFormula {
|
||||
mapping(bytes32 => uint) public id2index;
|
||||
mapping(bytes32 => bool) existingIDs;
|
||||
|
||||
event DAppCreated(bytes32 indexed id, uint votesMint, uint amount);
|
||||
event DAppCreated(bytes32 indexed id, uint newEffectiveBalance);
|
||||
event Upvote(bytes32 indexed id, uint newEffectiveBalance);
|
||||
event Downvote(bytes32 indexed id, uint newEffectiveBalance);
|
||||
event Withdraw(bytes32 indexed id, uint newEffectiveBalance);
|
||||
@ -61,7 +61,7 @@ contract DAppStore is ApproveAndCallFallBack, BancorFormula {
|
||||
|
||||
max = (total * ceiling) / decimals;
|
||||
|
||||
safeMax = 98 * max / 100;
|
||||
safeMax = 77 * max / 100; // Limited by accuracy of BancorFormula
|
||||
}
|
||||
|
||||
/**
|
||||
@ -197,7 +197,7 @@ contract DAppStore is ApproveAndCallFallBack, BancorFormula {
|
||||
uint dappIdx = id2index[_id];
|
||||
Data memory d = dapps[dappIdx];
|
||||
require(d.id == _id, "Error fetching correct data");
|
||||
require(d.balance + _amount < safeMax, "You cannot upvote by this much, try with a lower amount");
|
||||
require(d.balance + _amount <= safeMax, "You cannot upvote by this much, try with a lower amount");
|
||||
|
||||
// Special case - no downvotes yet cast
|
||||
if (d.votesCast == 0) {
|
||||
@ -250,7 +250,7 @@ contract DAppStore is ApproveAndCallFallBack, BancorFormula {
|
||||
require(!existingIDs[_id], "You must submit a unique ID");
|
||||
|
||||
require(_amount > 0, "You must spend some SNT to submit a ranking in order to avoid spam");
|
||||
require (_amount < safeMax, "You cannot stake more SNT than the ceiling dictates");
|
||||
require (_amount <= safeMax, "You cannot stake more SNT than the ceiling dictates");
|
||||
|
||||
uint dappIdx = dapps.length;
|
||||
|
||||
@ -283,7 +283,7 @@ contract DAppStore is ApproveAndCallFallBack, BancorFormula {
|
||||
require(SNT.allowance(_from, address(this)) >= _amount, "Not enough SNT allowance");
|
||||
require(SNT.transferFrom(_from, address(this), _amount), "Transfer failed");
|
||||
|
||||
emit DAppCreated(_id, d.votesMinted, d.effectiveBalance);
|
||||
emit DAppCreated(_id, d.effectiveBalance);
|
||||
}
|
||||
|
||||
function _upvote(address _from, bytes32 _id, uint _amount) internal {
|
||||
@ -293,7 +293,7 @@ contract DAppStore is ApproveAndCallFallBack, BancorFormula {
|
||||
Data storage d = dapps[dappIdx];
|
||||
require(d.id == _id, "Error fetching correct data");
|
||||
|
||||
require(d.balance + _amount < safeMax, "You cannot upvote by this much, try with a lower amount");
|
||||
require(d.balance + _amount <= safeMax, "You cannot upvote by this much, try with a lower amount");
|
||||
|
||||
uint precision;
|
||||
uint result;
|
||||
|
@ -45,10 +45,10 @@ contract("DAppStore", function () {
|
||||
it("should set max and safeMax values correctly", async function () {
|
||||
let resultMax = await DAppStore.methods.max().call();
|
||||
let resultSafeMax = await DAppStore.methods.safeMax().call();
|
||||
let expectedMax = Math.round(3470483788 * 588 / 1000000);
|
||||
let expectedSafeMax = Math.round(expectedMax * 0.98);
|
||||
assert.strictEqual(parseInt(resultMax, 10), expectedMax);
|
||||
assert.strictEqual(parseInt(resultSafeMax, 10), expectedSafeMax);
|
||||
let expectedMax = 3470483788 * 588 / 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 () {
|
||||
@ -590,4 +590,55 @@ contract("DAppStore", function () {
|
||||
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 temp = await DAppStore.methods.safeMax().call();
|
||||
let amount = parseInt(temp, 10);
|
||||
|
||||
await SNT.methods.generateTokens(accounts[0], amount).send();
|
||||
const encodedCall = DAppStore.methods.createDApp(id,amount).encodeABI();
|
||||
await SNT.methods.approveAndCall(DAppStore.options.address, amount, encodedCall).send({from: accounts[0]});
|
||||
|
||||
let receipt = await DAppStore.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(amount, parseInt(receipt.balance, 10));
|
||||
|
||||
let max = await DAppStore.methods.max().call();
|
||||
let decimals = await DAppStore.methods.decimals().call();
|
||||
let rate = Math.ceil(decimals - (amount * decimals/max));
|
||||
assert.strictEqual(rate, parseInt(receipt.rate, 10));
|
||||
|
||||
let available = amount * 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);
|
||||
})
|
||||
|
||||
it("should prove we have the highest safeMax allowed for by Bancor's power approximation", async function () {
|
||||
let id = "0x0000000000000000000000000000000000000000000000000000000000000002";
|
||||
let max = await DAppStore.methods.max().call();
|
||||
// Choose a safeMax 1% higher than is currently set
|
||||
let safe = await DAppStore.methods.safeMax().call();
|
||||
let amount = parseInt(max, 10) * (parseInt(safe, 10) + 1);
|
||||
|
||||
await SNT.methods.generateTokens(accounts[0], amount).send();
|
||||
const encodedCall = DAppStore.methods.createDApp(id,amount).encodeABI();
|
||||
|
||||
try {
|
||||
await SNT.methods.approveAndCall(DAppStore.options.address, amount, encodedCall).send({from: accounts[0]});
|
||||
} catch (error) {
|
||||
TestUtils.assertJump(error);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user