mirror of https://github.com/embarklabs/embark.git
282 lines
12 KiB
JavaScript
282 lines
12 KiB
JavaScript
/*global contract, config, it, assert, web3, before, describe, artifacts*/
|
|
/* eslint require-atomic-updates:0, no-await-in-loop:0*/
|
|
const TestUtils = require("../utils/testUtils");
|
|
|
|
const ArbitrationLicense = artifacts.require('ArbitrationLicense');
|
|
const OfferStore = artifacts.require('OfferStore');
|
|
const UserStore = artifacts.require('UserStore');
|
|
const Escrow = artifacts.require('Escrow');
|
|
const SNT = artifacts.require('SNT');
|
|
|
|
const ARBITRATION_SOLVED_SELLER = 2;
|
|
|
|
let accounts;
|
|
let arbitrator, blacklistedAccount;
|
|
|
|
const feePercent = 1;
|
|
const BURN_ADDRESS = "0x0000000000000000000000000000000000000002";
|
|
|
|
const CONTACT_DATA = "Status:0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB";
|
|
|
|
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": {},
|
|
"Medianizer": {},
|
|
"SNT": {
|
|
"instanceOf": "MiniMeToken",
|
|
"args": [
|
|
"$MiniMeTokenFactory",
|
|
"0x0000000000000000000000000000000000000000",
|
|
0,
|
|
"TestMiniMeToken",
|
|
18,
|
|
"STT",
|
|
true
|
|
]
|
|
},
|
|
License: {
|
|
deploy: false
|
|
},
|
|
ArbitrationLicense: {
|
|
args: ["$SNT", 10, BURN_ADDRESS]
|
|
},
|
|
SellerLicense: {
|
|
instanceOf: "License",
|
|
args: ["$SNT", 10, BURN_ADDRESS]
|
|
},
|
|
|
|
/*
|
|
StakingPool: {
|
|
file: 'staking-pool/contracts/StakingPool.sol',
|
|
args: ["$SNT"]
|
|
},
|
|
*/
|
|
|
|
UserStore: {
|
|
args: ["$SellerLicense", "$ArbitrationLicense"]
|
|
},
|
|
OfferStore: {
|
|
args: ["$UserStore", "$SellerLicense", "$ArbitrationLicense", BURN_ADDRESS, "$Medianizer"],
|
|
onDeploy: ["UserStore.methods.setAllowedContract('$OfferStore', true).send()"]
|
|
},
|
|
Escrow: {
|
|
args: ["$accounts[0]", "0x0000000000000000000000000000000000000000", "$ArbitrationLicense", "$OfferStore", "$UserStore", BURN_ADDRESS, feePercent * 1000],
|
|
onDeploy: [
|
|
"OfferStore.methods.setAllowedContract('$Escrow', true).send()",
|
|
"UserStore.methods.setAllowedContract('$Escrow', true).send()"
|
|
]
|
|
},
|
|
StandardToken: {}
|
|
}
|
|
}
|
|
}, (_err, web3_accounts) => {
|
|
accounts = web3_accounts;
|
|
arbitrator = accounts[8];
|
|
blacklistedAccount = accounts[5];
|
|
});
|
|
|
|
contract("Escrow", function() {
|
|
|
|
const tradeAmount = 100;
|
|
const feeAmount = Math.round(tradeAmount * (feePercent / 100));
|
|
|
|
let receipt, escrowId, ethOfferId, hash, signature, nonce;
|
|
let created;
|
|
let offerIds = [];
|
|
|
|
this.timeout(0);
|
|
|
|
before(async () => {
|
|
await SNT.methods.generateTokens(accounts[0], 1000).send();
|
|
await SNT.methods.generateTokens(blacklistedAccount, 1000).send();
|
|
|
|
// Register arbitrators
|
|
await SNT.methods.generateTokens(arbitrator, 1000).send();
|
|
|
|
const encodedCall2 = ArbitrationLicense.methods.buy().encodeABI();
|
|
await SNT.methods.approveAndCall(ArbitrationLicense.options.address, 10, encodedCall2).send({from: arbitrator});
|
|
await ArbitrationLicense.methods.changeAcceptAny(true).send({from: arbitrator});
|
|
await ArbitrationLicense.methods.blacklistSeller(blacklistedAccount).send({from: arbitrator});
|
|
});
|
|
|
|
describe("Offer Stake", async() => {
|
|
|
|
it("base price should be ~1usd", async() => {
|
|
const amountToStake = await OfferStore.methods.getAmountToStake(accounts[0]).call();
|
|
// Medianizer for this example has a value of "161567500000000000000", 161.5675 usd per eth
|
|
const oneUsd = (1 / 161.5675).toFixed(6);
|
|
const amountToStakeUsd = parseFloat(web3.utils.fromWei(amountToStake, "ether")).toFixed(6);
|
|
assert.strictEqual(oneUsd, amountToStakeUsd);
|
|
});
|
|
|
|
it("price for each offers should increase exponentially", async() => {
|
|
let amountToStake;
|
|
|
|
// 1st to 4th offer
|
|
for(let i = 0; i < 4; i++){
|
|
amountToStake = await OfferStore.methods.getAmountToStake(accounts[0]).call();
|
|
assert.strictEqual(amountToStake, "6189000000000000");
|
|
receipt = await OfferStore.methods.addOffer(TestUtils.zeroAddress, CONTACT_DATA, "London", "USD", "Iuri", [0], 0, 0, 1, arbitrator).send({from: accounts[0], value: amountToStake});
|
|
offerIds.push(receipt.events.OfferAdded.returnValues.offerId);
|
|
}
|
|
|
|
amountToStake = await OfferStore.methods.getAmountToStake(accounts[0]).call();
|
|
assert.strictEqual(amountToStake, "9101470588235294");
|
|
|
|
receipt = await OfferStore.methods.addOffer(TestUtils.zeroAddress, CONTACT_DATA, "London", "USD", "Iuri", [0], 0, 0, 1, arbitrator).send({from: accounts[0], value: amountToStake});
|
|
offerIds.push(receipt.events.OfferAdded.returnValues.offerId);
|
|
|
|
amountToStake = await OfferStore.methods.getAmountToStake(accounts[0]).call();
|
|
assert.strictEqual(amountToStake, "13106117647058823");
|
|
|
|
receipt = await OfferStore.methods.addOffer(TestUtils.zeroAddress, CONTACT_DATA, "London", "USD", "Iuri", [0], 0, 0, 1, arbitrator).send({from: accounts[0], value: amountToStake});
|
|
offerIds.push(receipt.events.OfferAdded.returnValues.offerId);
|
|
|
|
amountToStake = await OfferStore.methods.getAmountToStake(accounts[0]).call();
|
|
assert.strictEqual(amountToStake, "17838882352941176");
|
|
|
|
receipt = await OfferStore.methods.addOffer(TestUtils.zeroAddress, CONTACT_DATA, "London", "USD", "Iuri", [0], 0, 0, 1, arbitrator).send({from: accounts[0], value: amountToStake});
|
|
offerIds.push(receipt.events.OfferAdded.returnValues.offerId);
|
|
});
|
|
|
|
it("price should decrease for each offer exponentially", async() => {
|
|
let currOffer, amountToStake;
|
|
|
|
currOffer = offerIds.pop();
|
|
await OfferStore.methods.removeOffer(currOffer).send();
|
|
amountToStake = await OfferStore.methods.getAmountToStake(accounts[0]).call();
|
|
assert.strictEqual(amountToStake, "17838882352941176");
|
|
|
|
currOffer = offerIds.pop();
|
|
await OfferStore.methods.removeOffer(currOffer).send();
|
|
amountToStake = await OfferStore.methods.getAmountToStake(accounts[0]).call();
|
|
assert.strictEqual(amountToStake, "13106117647058823");
|
|
|
|
currOffer = offerIds.pop();
|
|
await OfferStore.methods.removeOffer(currOffer).send();
|
|
amountToStake = await OfferStore.methods.getAmountToStake(accounts[0]).call();
|
|
assert.strictEqual(amountToStake, "9101470588235294");
|
|
|
|
for(let i = 0; i < 3; i++){
|
|
currOffer = offerIds.pop();
|
|
await OfferStore.methods.removeOffer(currOffer).send();
|
|
amountToStake = await OfferStore.methods.getAmountToStake(accounts[0]).call();
|
|
assert.strictEqual(amountToStake, "6189000000000000");
|
|
}
|
|
});
|
|
|
|
it("deleting an offer should refund the stake", async() => {
|
|
let contractBalance, userBalance1, userBalance2;
|
|
|
|
ethOfferId = offerIds.pop();
|
|
|
|
userBalance1 = web3.utils.toBN(await web3.eth.getBalance(accounts[0]));
|
|
contractBalance = await web3.eth.getBalance(OfferStore.options.address);
|
|
assert.strictEqual(contractBalance, "6189000000000000");
|
|
|
|
receipt = await OfferStore.methods.removeOffer(ethOfferId).send();
|
|
contractBalance = await web3.eth.getBalance(OfferStore.options.address);
|
|
assert.strictEqual(contractBalance, web3.utils.toWei("0", "ether"));
|
|
|
|
userBalance2 = web3.utils.toBN(await web3.eth.getBalance(accounts[0]));
|
|
|
|
assert(userBalance1.lt(userBalance2), "User balance did not increase after refund");
|
|
});
|
|
|
|
it("price for each offers should keep increasing exponentially", async() => {
|
|
let amountToStake;
|
|
|
|
// 1st to 4th offer
|
|
for(let i = 0; i < 4; i++){
|
|
amountToStake = await OfferStore.methods.getAmountToStake(accounts[0]).call();
|
|
assert.strictEqual(amountToStake, "6189000000000000");
|
|
receipt = await OfferStore.methods.addOffer(TestUtils.zeroAddress, CONTACT_DATA, "London", "USD", "Iuri", [0], 0, 0, 1, arbitrator).send({from: accounts[0], value: amountToStake});
|
|
}
|
|
|
|
amountToStake = await OfferStore.methods.getAmountToStake(accounts[0]).call();
|
|
assert.strictEqual(amountToStake, "9101470588235294");
|
|
});
|
|
|
|
it("releasing an escrow should refund the stake and decrease next offer price", async() => {
|
|
let userBalance1, userBalance2;
|
|
|
|
// Create Offer
|
|
const amountToStake = await OfferStore.methods.getAmountToStake(accounts[0]).call();
|
|
assert.strictEqual(amountToStake, "9101470588235294");
|
|
|
|
receipt = await OfferStore.methods.addOffer(TestUtils.zeroAddress, CONTACT_DATA, "London", "USD", "Iuri", [0], 0, 0, 1, arbitrator).send({from: accounts[0], value: amountToStake});
|
|
ethOfferId = receipt.events.OfferAdded.returnValues.offerId;
|
|
|
|
userBalance1 = web3.utils.toBN(await web3.eth.getBalance(accounts[0]));
|
|
|
|
// Create Escrow
|
|
receipt = await Escrow.methods.createEscrow(ethOfferId, tradeAmount, 140, accounts[1], CONTACT_DATA, "L", "U").send({from: accounts[1]});
|
|
created = receipt.events.Created;
|
|
escrowId = created.returnValues.escrowId;
|
|
|
|
// Fund Escrow
|
|
receipt = await Escrow.methods.fund(escrowId).send({from: accounts[0], value: tradeAmount + feeAmount});
|
|
|
|
// Release Escrow
|
|
receipt = await Escrow.methods.release(escrowId).send({from: accounts[0]});
|
|
|
|
userBalance2 = web3.utils.toBN(await web3.eth.getBalance(accounts[0]));
|
|
assert(userBalance1.lt(userBalance2), "User balance did not increase after refund");
|
|
|
|
const stakeDetails = await OfferStore.methods.stakes(ethOfferId).call();
|
|
assert.strictEqual(stakeDetails.amount, "0");
|
|
});
|
|
|
|
it("price for next offer should not increase", async() => {
|
|
const amountToStake = await OfferStore.methods.getAmountToStake(accounts[0]).call();
|
|
assert.strictEqual(amountToStake, "9101470588235294");
|
|
});
|
|
|
|
it("winning a dispute should not release the stake (only succesful trades do)", async() => {
|
|
let initialContractBalance, finalContractBalance;
|
|
|
|
// Create Offer
|
|
const amountToStake = await OfferStore.methods.getAmountToStake(accounts[0]).call();
|
|
receipt = await OfferStore.methods.addOffer(TestUtils.zeroAddress, CONTACT_DATA, "London", "USD", "Iuri", [0], 0, 0, 1, arbitrator).send({from: accounts[0], value: amountToStake});
|
|
ethOfferId = receipt.events.OfferAdded.returnValues.offerId;
|
|
|
|
initialContractBalance = await web3.eth.getBalance(OfferStore.options.address);
|
|
|
|
// Create Escrow
|
|
hash = await UserStore.methods.getDataHash("U", CONTACT_DATA).call({from: accounts[1]});
|
|
signature = await web3.eth.sign(hash, accounts[1]);
|
|
nonce = await UserStore.methods.user_nonce(accounts[1]).call();
|
|
receipt = await Escrow.methods.createEscrow(ethOfferId, tradeAmount, 140, accounts[1], CONTACT_DATA, "L", "U", nonce, signature).send({from: accounts[1]});
|
|
created = receipt.events.Created;
|
|
escrowId = created.returnValues.escrowId;
|
|
|
|
// Fund Escrow
|
|
receipt = await Escrow.methods.fund(escrowId).send({from: accounts[0], value: tradeAmount + feeAmount});
|
|
|
|
// Pay Escrow
|
|
await Escrow.methods.pay(escrowId).send({from: accounts[1]});
|
|
|
|
// Open dispute
|
|
await Escrow.methods.openCase(escrowId, '1').send({from: accounts[1]});
|
|
|
|
// Seller wins dispute
|
|
receipt = await Escrow.methods.setArbitrationResult(escrowId, ARBITRATION_SOLVED_SELLER).send({from: arbitrator});
|
|
|
|
finalContractBalance = await web3.eth.getBalance(OfferStore.options.address);
|
|
assert.strictEqual(finalContractBalance, initialContractBalance);
|
|
});
|
|
});
|
|
|
|
});
|