Adapted to runethtx

This commit is contained in:
Jordi Baylina 2017-07-13 19:12:45 +02:00
parent 978dbae46d
commit 76fce0d06e
No known key found for this signature in database
GPG Key ID: 7480C80C1BE43112
12 changed files with 7659 additions and 1421 deletions

View File

@ -1,52 +1,7 @@
{
"env": {
"browser": true,
"es6": true,
"node": true,
"mocha": true
},
"extends": "airbnb",
"parser": "babel-eslint",
"rules": {
// indentation
"indent": [ 2, 4 ],
// spacing
"template-curly-spacing": [ 2, "always" ],
"array-bracket-spacing": [ 2, "always" ],
"object-curly-spacing": [ 2, "always" ],
"computed-property-spacing": [ 2, "always" ],
"no-multiple-empty-lines": [ 2, { "max": 1, "maxEOF": 0, "maxBOF": 0 } ],
// strings
"quotes": [ 2, "double", "avoid-escape" ],
// code arrangement matter
"no-use-before-define": [ 2, { "functions": false } ],
// make it meaningful
"prefer-const": 1,
// keep it simple
"complexity": [ 1, 5 ],
// Consisten return
"consistent-return": 0,
"import/no-extraneous-dependencies": ["error", {"devDependencies": ["**/*.test.js", "**/*.spec.js", "**/compile.js", "**/test/*.js"]}],
// react
"react/prefer-es6-class": 0,
"react/jsx-filename-extension": 0,
"react/jsx-indent": [ 2, 4 ],
"jsx-a11y/href-no-hash": "off",
"jsx-a11y/anchor-is-valid": ["warn", { "aspects": ["invalidHref"] }]
},
"globals": {
"artifacts": true,
"web3": true,
"contract": true,
"assert": true
}
}

View File

@ -21,14 +21,14 @@ contract LiquidPledging is LiquidPledgingBase {
/// @param idReceiver To who it's transfered. Can ve the same donnor, another
/// donor, a delegate or a project
function donate(uint64 idDonor, uint64 idReceiver) payable {
NoteManager sender = findManager(idDonor);
NoteManager storage sender = findManager(idDonor);
if (sender.managerType != NoteManagerType.Donor) throw;
if (sender.addr != msg.sender) throw;
require(sender.managerType == NoteManagerType.Donor);
require(sender.addr == msg.sender);
uint amount = msg.value;
if (amount == 0) throw;
require(amount > 0);
vault.transfer(amount);
uint64 idNote = findNote(
@ -40,7 +40,7 @@ contract LiquidPledging is LiquidPledgingBase {
PaymentState.NotPaid);
Note nTo = findNote(idNote);
Note storage nTo = findNote(idNote);
nTo.amount += amount;
Transfer(0, idNote, amount);
@ -60,12 +60,12 @@ contract LiquidPledging is LiquidPledgingBase {
idNote = normalizeNote(idNote);
Note n = findNote(idNote);
NoteManager receiver = findManager(idReceiver);
NoteManager sender = findManager(idSender);
Note storage n = findNote(idNote);
NoteManager storage receiver = findManager(idReceiver);
NoteManager storage sender = findManager(idSender);
if (sender.addr != msg.sender) throw;
if (n.paymentState != PaymentState.NotPaid) throw;
require(sender.addr == msg.sender);
require(n.paymentState == PaymentState.NotPaid);
// If the sender is the owner
if (n.owner == idSender) {
@ -76,7 +76,7 @@ contract LiquidPledging is LiquidPledgingBase {
} else if (receiver.managerType == NoteManagerType.Delegate) {
appendDelegate(idNote, amount, idReceiver);
} else {
throw;
assert(false);
}
return;
}
@ -88,11 +88,8 @@ contract LiquidPledging is LiquidPledgingBase {
// If the receiver is another doner
if (receiver.managerType == NoteManagerType.Donor) {
// Only accept to change to the original donor to remove all delegates
if (n.owner == idReceiver) {
undelegate(idNote, amount, n.delegationChain.length);
} else {
throw;
}
assert(n.owner == idReceiver);
undelegate(idNote, amount, n.delegationChain.length);
return;
}
@ -122,7 +119,7 @@ contract LiquidPledging is LiquidPledgingBase {
return;
}
}
throw; // It is not the owner nor any delegate.
assert(false); // It is not the owner nor any delegate.
}
@ -135,13 +132,13 @@ contract LiquidPledging is LiquidPledgingBase {
idNote = normalizeNote(idNote);
Note n = findNote(idNote);
Note storage n = findNote(idNote);
if (n.paymentState != PaymentState.NotPaid) throw;
require(n.paymentState == PaymentState.NotPaid);
NoteManager owner = findManager(n.owner);
NoteManager storage owner = findManager(n.owner);
if (owner.addr != msg.sender) throw;
require(owner.addr == msg.sender);
uint64 idNewNote = findNote(
n.owner,
@ -161,12 +158,12 @@ contract LiquidPledging is LiquidPledgingBase {
/// @param idNote Id of the note that wants to be withdrawed.
/// @param amount Quantity of Ether that wants to be withdrawed.
function confirmPayment(uint64 idNote, uint amount) onlyVault {
Note n = findNote(idNote);
Note storage n = findNote(idNote);
if (n.paymentState != PaymentState.Paying) throw;
require(n.paymentState == PaymentState.Paying);
// Check the project is not canceled in the while.
if (getOldestNoteNotCanceled(idNote) != idNote) throw;
require(getOldestNoteNotCanceled(idNote) == idNote);
uint64 idNewNote = findNote(
n.owner,
@ -184,9 +181,9 @@ contract LiquidPledging is LiquidPledgingBase {
/// @param idNote Id of the note that wants to be canceled for withdraw.
/// @param amount Quantity of Ether that wants to be rolled back.
function cancelPayment(uint64 idNote, uint amount) onlyVault {
Note n = findNote(idNote);
Note storage n = findNote(idNote);
if (n.paymentState != PaymentState.Paying) throw;
require(n.paymentState == PaymentState.Paying);
// When a payment is cacnceled, never is assigned to a project.
uint64 oldNote = findNote(
@ -206,7 +203,7 @@ contract LiquidPledging is LiquidPledgingBase {
/// @notice Method called by the reviewer of a project to cancel this project.
/// @param idProject Id of the projct that wants to be canceled.
function cancelProject(uint64 idProject) {
NoteManager project = findManager(idProject);
NoteManager storage project = findManager(idProject);
require((project.reviewer == msg.sender) || (project.addr == msg.sender));
project.canceled = true;
}
@ -258,9 +255,9 @@ contract LiquidPledging is LiquidPledgingBase {
function transferOwnershipToProject(uint64 idNote, uint amount, uint64 idReceiver) internal {
Note n = findNote(idNote);
Note storage n = findNote(idNote);
if (getProjectLevel(n) >= MAX_SUBPROJECT_LEVEL) throw;
require(getProjectLevel(n) < MAX_SUBPROJECT_LEVEL);
uint64 oldNote = findNote(
n.owner,
n.delegationChain,
@ -283,7 +280,7 @@ contract LiquidPledging is LiquidPledgingBase {
function transferOwnershipToDonor(uint64 idNote, uint amount, uint64 idReceiver) internal {
// If the owner does not change, then just let it this way.
Note n = findNote(idNote);
Note storage n = findNote(idNote);
if (n.owner == idReceiver) return;
uint64 toNote = findNote(
@ -297,9 +294,9 @@ contract LiquidPledging is LiquidPledgingBase {
}
function appendDelegate(uint64 idNote, uint amount, uint64 idReceiver) internal {
Note n = findNote(idNote);
Note storage n= findNote(idNote);
if (n.delegationChain.length >= MAX_DELEGATES) throw;
require(n.delegationChain.length < MAX_DELEGATES);
uint64[] memory newDelegationChain = new uint64[](n.delegationChain.length + 1);
for (uint i=0; i<n.delegationChain.length; i++) {
newDelegationChain[i] = n.delegationChain[i];
@ -317,7 +314,7 @@ contract LiquidPledging is LiquidPledgingBase {
/// @param q Unmber of undelegations
function undelegate(uint64 idNote, uint amount, uint q) internal {
Note n = findNote(idNote);
Note storage n = findNote(idNote);
uint64[] memory newDelegationChain = new uint64[](n.delegationChain.length - q);
for (uint i=0; i<n.delegationChain.length - q; i++) {
newDelegationChain[i] = n.delegationChain[i];
@ -334,11 +331,11 @@ contract LiquidPledging is LiquidPledgingBase {
function proposeAssignProject(uint64 idNote, uint amount, uint64 idReceiver) internal {
Note n = findNote(idNote);
Note storage n = findNote(idNote);
if (getProjectLevel(n) >= MAX_SUBPROJECT_LEVEL) throw;
require(getProjectLevel(n) < MAX_SUBPROJECT_LEVEL);
NoteManager owner = findManager(n.owner);
NoteManager storage owner = findManager(n.owner);
uint64 toNote = findNote(
n.owner,
n.delegationChain,
@ -352,9 +349,9 @@ contract LiquidPledging is LiquidPledgingBase {
function doTransfer(uint64 from, uint64 to, uint amount) internal {
if (from == to) return;
if (amount == 0) return;
Note nFrom = findNote(from);
Note nTo = findNote(to);
if (nFrom.amount < amount) throw;
Note storage nFrom = findNote(from);
Note storage nTo = findNote(to);
require(nFrom.amount >= amount);
nFrom.amount -= amount;
nTo.amount += amount;
@ -362,7 +359,7 @@ contract LiquidPledging is LiquidPledgingBase {
}
function normalizeNote(uint64 idNote) internal returns(uint64) {
Note n = findNote(idNote);
Note storage n = findNote(idNote);
if (n.paymentState != PaymentState.NotPaid) return idNote;
// First send to a project if it's proposed and commited

View File

@ -1,6 +1,8 @@
pragma solidity ^0.4.11;
import "./Vault.sol";
contract Vault {
function authorizePayment(bytes32 _ref, address _dest, uint _amount);
}
contract LiquidPledgingBase {
@ -39,7 +41,7 @@ contract LiquidPledgingBase {
/////
modifier onlyVault() {
if (msg.sender != address(vault)) throw;
require(msg.sender == address(vault));
_;
}
@ -79,9 +81,9 @@ contract LiquidPledgingBase {
string newName,
uint64 newCommitTime)
{
NoteManager donor = findManager(idDonor);
if (donor.managerType != NoteManagerType.Donor) throw;
if (donor.addr != msg.sender) throw;
NoteManager storage donor = findManager(idDonor);
require(donor.managerType == NoteManagerType.Donor);
require(donor.addr == msg.sender);
donor.addr = newAddr;
donor.name = newName;
donor.commitTime = newCommitTime;
@ -105,9 +107,9 @@ contract LiquidPledgingBase {
event DeegateAdded(uint64 indexed idMember);
function updateDelegate(uint64 idDelegate, address newAddr, string newName) {
NoteManager delegate = findManager(idDelegate);
if (delegate.managerType != NoteManagerType.Delegate) throw;
if (delegate.addr != msg.sender) throw;
NoteManager storage delegate = findManager(idDelegate);
require(delegate.managerType == NoteManagerType.Delegate);
require(delegate.addr == msg.sender);
delegate.addr = newAddr;
delegate.name = newName;
DelegateUpdated(idDelegate);
@ -130,9 +132,9 @@ contract LiquidPledgingBase {
event ProjectAdded(uint64 indexed idMember);
function updateProject(uint64 idProject, address newAddr, string newName, uint64 newCommitTime) {
NoteManager project = findManager(idProject);
if (project.managerType != NoteManagerType.Project) throw;
if (project.addr != msg.sender) throw;
NoteManager storage project = findManager(idProject);
require(project.managerType == NoteManagerType.Project);
require(project.addr == msg.sender);
project.addr = newAddr;
project.name = newName;
project.commitTime = newCommitTime;
@ -140,9 +142,9 @@ contract LiquidPledgingBase {
}
function updateProjectCanceler(uint64 idProject, address newReviewer) {
NoteManager project = findManager(idProject);
if (project.managerType != NoteManagerType.Project) throw;
if (project.reviewer != msg.sender) throw;
NoteManager storage project = findManager(idProject);
require(project.managerType == NoteManagerType.Project);
require(project.reviewer == msg.sender);
project.reviewer = newReviewer;
ProjectUpdated(idProject);
}
@ -168,7 +170,7 @@ contract LiquidPledgingBase {
uint64 oldNote,
PaymentState paymentState
) {
Note n = findNote(idNote);
Note storage n = findNote(idNote);
amount = n.amount;
owner = n.owner;
nDelegates = uint64(n.delegationChain.length);
@ -183,9 +185,9 @@ contract LiquidPledgingBase {
address addr,
string name
) {
Note n = findNote(idNote);
Note storage n = findNote(idNote);
idDelegate = n.delegationChain[idxDelegate - 1];
NoteManager delegate = findManager(idDelegate);
NoteManager storage delegate = findManager(idDelegate);
addr = delegate.addr;
name = delegate.name;
}
@ -202,7 +204,7 @@ contract LiquidPledgingBase {
address reviewer,
bool canceled)
{
NoteManager m = findManager(idManager);
NoteManager storage m = findManager(idManager);
managerType = m.managerType;
addr = m.addr;
name = m.name;
@ -234,19 +236,19 @@ contract LiquidPledgingBase {
}
function findManager(uint64 idManager) internal returns (NoteManager storage) {
if (idManager >= managers.length) throw;
require(idManager < managers.length);
return managers[idManager];
}
function findNote(uint64 idNote) internal returns (Note storage) {
if (idNote >= notes.length) throw;
require(idNote < notes.length);
return notes[idNote];
}
function getOldestNoteNotCanceled(uint64 idNote) internal constant returns(uint64) {
if (idNote == 0) return 0;
Note n = findNote(idNote);
NoteManager owner = findManager(n.owner);
Note storage n = findNote(idNote);
NoteManager storage owner = findManager(n.owner);
if (owner.managerType == NoteManagerType.Donor) return idNote;
uint64 parentProject = getOldestNoteNotCanceled(n.oldNote);
@ -270,7 +272,7 @@ contract LiquidPledgingBase {
function getProjectLevel(Note n) internal returns(uint) {
if (n.oldNote == 0) return 1;
Note oldN = findNote(n.oldNote);
Note storage oldN = findNote(n.oldNote);
return getProjectLevel(oldN) + 1;
}

View File

@ -1,8 +1,8 @@
pragma solidity ^0.4.11;
import '../LiquidPledging.sol';
import "./LiquidPledging.sol";
// @dev DevTokensHolderMock mocks current block number
// @dev LiquidPledgingMock mocks current block number
contract LiquidPledgingMock is LiquidPledging {

View File

@ -1,7 +1,11 @@
pragma solidity ^0.4.11;
import "./Owned.sol";
import "./LiquidPledging.sol";
contract LiquidPledging {
function confirmPayment(uint64 idNote, uint amount);
function cancelPayment(uint64 idNote, uint amount);
}
contract Vault is Owned {
@ -66,7 +70,7 @@ contract Vault is Owned {
function doConfirmPayment(uint _idPayment) internal {
require(_idPayment < payments.length);
Payment p = payments[_idPayment];
Payment storage p = payments[_idPayment];
require(p.state == PaymentState.Pending);
p.state = PaymentState.Paid;
@ -83,7 +87,7 @@ contract Vault is Owned {
function doCancelPayment(uint _idPayment) internal {
require(_idPayment < payments.length);
Payment p = payments[_idPayment];
Payment storage p = payments[_idPayment];
require(p.state == PaymentState.Pending);
p.state = PaymentState.Canceled;

View File

@ -1,9 +1,17 @@
const LiquidPledgingAbi = require("../build/contracts/LiquidPledging.json").abi;
const LiquidPledgingAbi = require("../build/LiquidPledging.sol").LiquidPledgingAbi;
const LiquidPledgingCode = require("../build/LiquidPledging.sol").LiquidPledgingByteCode;
const LiquidPledgingMockAbi = require("../build/LiquidPledgingMock.sol").LiquidPledgingMockAbi;
const LiquidPledgingMockCode = require("../build/LiquidPledgingMock.sol").LiquidPledgingMockByteCode;
const runethtx = require("runethtx");
module.exports = class LiquidPledging {
module.exports = (test) => {
const LiquidPladgingContract = test ?
runethtx.generateClass(LiquidPledgingMockAbi, LiquidPledgingMockCode) :
runethtx.generateClass(LiquidPledgingAbi, LiquidPledgingCode);
return class LiquidPledging extends LiquidPladgingContract {
constructor(web3, address) {
this.web3 = web3;
this.address = address;
super(web3, address);
this.notes = [];
this.managers = [];
}
@ -110,4 +118,5 @@ module.exports = class LiquidPledging {
this.donorsState = donorsState;
}
};
};

5
js/vault.js Normal file
View File

@ -0,0 +1,5 @@
const VaultAbi = require("../build/Vault.sol").VaultAbi;
const VaultByteCode = require("../build/Vault.sol").VaultByteCode;
const runethtx = require("runethtx");
module.exports = runethtx.generateClass(VaultAbi, VaultByteCode);

8794
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -42,6 +42,9 @@
},
"homepage": "https://github.com/Giveth/liquidpledging#readme",
"dependencies": {
"babel-eslint": "^7.2.3"
"babel-eslint": "^7.2.3",
"chai": "^4.1.0",
"ethconnector": "0.0.25",
"runethtx": "0.0.9"
}
}

View File

@ -1,6 +1,10 @@
const LiquidPledging = artifacts.require("LiquidPledgingMock");
const Vault = artifacts.require("Vault");
const ethConnector = require('ethconnector');
const chai = require('chai');
const assert = chai.assert;
const LiquidPledging = require('../js/liquidPledging.js')(true);
const Vault = require('../js/vault.js');
const assertFail = require("./helpers/assertFail");
const getBalance = require("runethtx").getBalance;
const getNote = async (liquidPledging, idNote) => {
const note = {
@ -90,21 +94,36 @@ const printBalances = async(liquidPledging) => {
}
};
contract("LiquidPledging", (accounts) => {
describe("LiquidPledging test", () => {
let web3;
let accounts;
let liquidPledging;
let vault;
let donor1 = accounts[1];
let delegate1 = accounts[2];
let adminProject1 = accounts[3];
let adminProject2 = accounts[4];
let adminProject2a = accounts[5];
let delegate2 = accounts[6];
let reviewer = accounts[7];
let donor1;
let delegate1;
let adminProject1;
let adminProject2;
let adminProject2a;
let delegate2;
let reviewer;
before((done) => {
ethConnector.init("testrpc", { gasLimit: 4000000 }, () => {
web3 = ethConnector.web3;
accounts = ethConnector.accounts;
donor1 = accounts[1];
delegate1 = accounts[2];
adminProject1 = accounts[3];
adminProject2 = accounts[4];
adminProject2a = accounts[5];
delegate2 = accounts[6];
reviewer = accounts[7];
done();
});
});
it("Should deploy LiquidPledgin contract", async () => {
vault = await Vault.new();
liquidPledging = await LiquidPledging.new(vault.address);
await vault.setLiquidPledging(liquidPledging.address);
vault = await Vault.new(web3);
liquidPledging = await LiquidPledging.new(web3, vault.$address);
await vault.setLiquidPledging(liquidPledging.$address);
});
it("Should create a donor", async () => {
await liquidPledging.addDonor("Donor1", 86400, {from: donor1});
@ -181,7 +200,7 @@ contract("LiquidPledging", (accounts) => {
assert.equal(res3[1].toNumber(), 1); // Owner
assert.equal(res3[2].toNumber(), 1); // Delegates
assert.equal(res3[3].toNumber(), 3); // Proposed Project
assert.isAbove(res3[4], n + 86000);
assert.isAbove(res3[4].toNumber(), n + 86000);
assert.equal(res3[5].toNumber(), 0); // Old Node
assert.equal(res3[6].toNumber(), 0); // Not Paid
});
@ -224,10 +243,10 @@ contract("LiquidPledging", (accounts) => {
assert.equal(res6[6].toNumber(), 1); // Peinding paid Paid
});
it("Should collect the Ether", async () => {
const initialBalance = await web3.eth.getBalance(adminProject1);
const initialBalance = await getBalance(web3, adminProject1);
await vault.confirmPayment(0);
const finalBalance = await web3.eth.getBalance(adminProject1);
const finalBalance = await getBalance(web3, adminProject1);
const collected = web3.fromWei(finalBalance.sub(initialBalance)).toNumber();
@ -257,7 +276,7 @@ contract("LiquidPledging", (accounts) => {
});
});
it("Delegate should send part of this ETH to project2", async () => {
await liquidPledging.transfer(2, 5, web3.toWei(0.03), 4, {from: delegate1});
await liquidPledging.transfer(2, 5, web3.toWei(0.03), 4,{$extraGas: 100000}, {from: delegate1});
const st = await getState(liquidPledging);
assert.equal(st.notes.length, 9);
assert.equal(web3.fromWei(st.notes[ 8 ].amount).toNumber(), 0.03);
@ -292,7 +311,7 @@ contract("LiquidPledging", (accounts) => {
assert.equal(st.notes.length, 11);
assert.equal(web3.fromWei(st.notes[ 9 ].amount).toNumber(), 0.01);
assert.equal(web3.fromWei(st.notes[ 10 ].amount).toNumber(), 0.01);
});
}).timeout(4000);
it("project2a authorize to spend a little", async () => {
const n = Math.floor(new Date().getTime() / 1000);
await liquidPledging.setMockedTime(n + 86401*3);
@ -302,7 +321,7 @@ contract("LiquidPledging", (accounts) => {
assert.equal(web3.fromWei(st.notes[ 10 ].amount).toNumber(), 0);
assert.equal(web3.fromWei(st.notes[ 11 ].amount).toNumber(), 0.005);
assert.equal(web3.fromWei(st.notes[ 12 ].amount).toNumber(), 0.005);
});
}).timeout(4000);
it("project2 is canceled", async () => {
await liquidPledging.cancelProject(4, {from: reviewer});
});
@ -326,21 +345,20 @@ contract("LiquidPledging", (accounts) => {
});
it("original owner should recover the remaining funds", async () => {
const st = await getState(liquidPledging);
await liquidPledging.withdraw(1, web3.toWei(0.5), {from: donor1});
await liquidPledging.withdraw(2, web3.toWei(0.31), {from: donor1});
await liquidPledging.withdraw(4, web3.toWei(0.1), {from: donor1});
await liquidPledging.withdraw(8, web3.toWei(0.03), {from: donor1});
await liquidPledging.withdraw(8, web3.toWei(0.03), {$extraGas: 100000}, {from: donor1});
await liquidPledging.withdraw(9, web3.toWei(0.01), {from: donor1});
const initialBalance = await web3.eth.getBalance(donor1);
const initialBalance = await getBalance(web3, donor1);
await vault.multiConfirm([2,3,4,5,6]);
const finalBalance = await web3.eth.getBalance(donor1);
const finalBalance = await getBalance(web3, donor1);
const collected = web3.fromWei(finalBalance.sub(initialBalance)).toNumber();
assert.equal(collected, 0.95);
});
}).timeout(8000);
});

View File

@ -1,3 +1,6 @@
const chai = require('chai');
const assert = chai.assert;
module.exports = async function(callback) {
let web3_error_thrown = false;
try {

4
tmp/xx.js Normal file
View File

@ -0,0 +1,4 @@
require('runethtx')
console.log('hh');