mirror of
https://github.com/status-im/liquid-funding.git
synced 2025-02-17 05:46:24 +00:00
Merge remote-tracking branch 'upstream/master' into add_donor_on_donate
This commit is contained in:
commit
cea412426d
6
build/ILiquidPledgingPlugin.sol.js
Normal file
6
build/ILiquidPledgingPlugin.sol.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
/* This is an autogenerated file. DO NOT EDIT MANUALLY */
|
||||||
|
|
||||||
|
exports.ILiquidPledgingPluginAbi = [{"constant":false,"inputs":[{"name":"noteManager","type":"uint64"},{"name":"noteFrom","type":"uint64"},{"name":"noteTo","type":"uint64"},{"name":"context","type":"uint64"},{"name":"amount","type":"uint256"}],"name":"afterTransfer","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"noteManager","type":"uint64"},{"name":"noteFrom","type":"uint64"},{"name":"noteTo","type":"uint64"},{"name":"context","type":"uint64"},{"name":"amount","type":"uint256"}],"name":"beforeTransfer","outputs":[{"name":"maxAllowed","type":"uint256"}],"payable":false,"type":"function"}]
|
||||||
|
exports.ILiquidPledgingPluginByteCode = "0x"
|
||||||
|
exports._solcVersion = "0.4.15+commit.bbb8e64f.Emscripten.clang"
|
||||||
|
exports._sha256 = "0x0b78eb5f7fc9ad0a36150ca9c8750a9d2e1fc98fa75dbf9627f3abdd201119c4"
|
21
build/ILiquidPledgingPlugin_all.sol
Normal file
21
build/ILiquidPledgingPlugin_all.sol
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
//File: ./contracts/ILiquidPledgingPlugin.sol
|
||||||
|
pragma solidity ^0.4.11;
|
||||||
|
|
||||||
|
contract ILiquidPledgingPlugin {
|
||||||
|
|
||||||
|
/// @param context In which context it is affected.
|
||||||
|
/// 0 -> owner from
|
||||||
|
/// 1 -> First delegate from
|
||||||
|
/// 2 -> Second delegate from
|
||||||
|
/// ...
|
||||||
|
/// 255 -> proposedProject from
|
||||||
|
///
|
||||||
|
/// 256 -> owner to
|
||||||
|
/// 257 -> First delegate to
|
||||||
|
/// 258 -> Second delegate to
|
||||||
|
/// ...
|
||||||
|
/// 511 -> proposedProject to
|
||||||
|
function beforeTransfer(uint64 noteManager, uint64 noteFrom, uint64 noteTo, uint64 context, uint amount) returns (uint maxAllowed);
|
||||||
|
function afterTransfer(uint64 noteManager, uint64 noteFrom, uint64 noteTo, uint64 context, uint amount);
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,7 +1,30 @@
|
|||||||
|
|
||||||
|
//File: contracts/ILiquidPledgingPlugin.sol
|
||||||
|
pragma solidity ^0.4.11;
|
||||||
|
|
||||||
|
contract ILiquidPledgingPlugin {
|
||||||
|
|
||||||
|
/// @param context In which context it is affected.
|
||||||
|
/// 0 -> owner from
|
||||||
|
/// 1 -> First delegate from
|
||||||
|
/// 2 -> Second delegate from
|
||||||
|
/// ...
|
||||||
|
/// 255 -> proposedProject from
|
||||||
|
///
|
||||||
|
/// 256 -> owner to
|
||||||
|
/// 257 -> First delegate to
|
||||||
|
/// 258 -> Second delegate to
|
||||||
|
/// ...
|
||||||
|
/// 511 -> proposedProject to
|
||||||
|
function beforeTransfer(uint64 noteManager, uint64 noteFrom, uint64 noteTo, uint64 context, uint amount) returns (uint maxAllowed);
|
||||||
|
function afterTransfer(uint64 noteManager, uint64 noteFrom, uint64 noteTo, uint64 context, uint amount);
|
||||||
|
}
|
||||||
|
|
||||||
//File: ./contracts/LiquidPledgingBase.sol
|
//File: ./contracts/LiquidPledgingBase.sol
|
||||||
pragma solidity ^0.4.11;
|
pragma solidity ^0.4.11;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
contract Vault {
|
contract Vault {
|
||||||
function authorizePayment(bytes32 _ref, address _dest, uint _amount);
|
function authorizePayment(bytes32 _ref, address _dest, uint _amount);
|
||||||
function () payable;
|
function () payable;
|
||||||
@ -24,6 +47,7 @@ contract LiquidPledgingBase {
|
|||||||
uint64 commitTime; // Only used in donors and projects, its the precommitment time
|
uint64 commitTime; // Only used in donors and projects, its the precommitment time
|
||||||
uint64 parentProject; // Only for projects
|
uint64 parentProject; // Only for projects
|
||||||
bool canceled; // Only for project
|
bool canceled; // Only for project
|
||||||
|
ILiquidPledgingPlugin plugin; // Handler that is called when one call is affected.
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Note {
|
struct Note {
|
||||||
@ -69,16 +93,20 @@ contract LiquidPledgingBase {
|
|||||||
// Managers functions
|
// Managers functions
|
||||||
//////
|
//////
|
||||||
|
|
||||||
function addDonor(string name, uint64 commitTime) {//Todo return idManager
|
function addDonor(string name, uint64 commitTime, ILiquidPledgingPlugin plugin) returns (uint64 idDonor) {//Todo return idManager
|
||||||
|
|
||||||
|
idDonor = uint64(managers.length);
|
||||||
|
|
||||||
managers.push(NoteManager(
|
managers.push(NoteManager(
|
||||||
NoteManagerType.Donor,
|
NoteManagerType.Donor,
|
||||||
msg.sender,
|
msg.sender,
|
||||||
name,
|
name,
|
||||||
commitTime,
|
commitTime,
|
||||||
0,
|
0,
|
||||||
false));
|
false,
|
||||||
|
plugin));
|
||||||
|
|
||||||
DonorAdded(uint64(managers.length-1));
|
DonorAdded(idDonor);
|
||||||
}
|
}
|
||||||
|
|
||||||
event DonorAdded(uint64 indexed idDonor);
|
event DonorAdded(uint64 indexed idDonor);
|
||||||
@ -100,52 +128,71 @@ contract LiquidPledgingBase {
|
|||||||
|
|
||||||
event DonorUpdated(uint64 indexed idDonor);
|
event DonorUpdated(uint64 indexed idDonor);
|
||||||
|
|
||||||
function addDelegate(string name) { //TODO return index number
|
function addDelegate(string name, uint64 commitTime, ILiquidPledgingPlugin plugin) returns (uint64 idDelegate) { //TODO return index number
|
||||||
|
|
||||||
|
idDelegate = uint64(managers.length);
|
||||||
|
|
||||||
managers.push(NoteManager(
|
managers.push(NoteManager(
|
||||||
NoteManagerType.Delegate,
|
NoteManagerType.Delegate,
|
||||||
msg.sender,
|
msg.sender,
|
||||||
name,
|
name,
|
||||||
|
commitTime,
|
||||||
0,
|
0,
|
||||||
0,
|
false,
|
||||||
false));
|
plugin));
|
||||||
|
|
||||||
DeegateAdded(uint64(managers.length-1));
|
DeegateAdded(idDelegate);
|
||||||
}
|
}
|
||||||
|
|
||||||
event DeegateAdded(uint64 indexed idDelegate);
|
event DeegateAdded(uint64 indexed idDelegate);
|
||||||
|
|
||||||
function updateDelegate(uint64 idDelegate, address newAddr, string newName) {
|
function updateDelegate(
|
||||||
|
uint64 idDelegate,
|
||||||
|
address newAddr,
|
||||||
|
string newName,
|
||||||
|
uint64 newCommitTime) {
|
||||||
NoteManager storage delegate = findManager(idDelegate);
|
NoteManager storage delegate = findManager(idDelegate);
|
||||||
require(delegate.managerType == NoteManagerType.Delegate);
|
require(delegate.managerType == NoteManagerType.Delegate);
|
||||||
require(delegate.addr == msg.sender);
|
require(delegate.addr == msg.sender);
|
||||||
delegate.addr = newAddr;
|
delegate.addr = newAddr;
|
||||||
delegate.name = newName;
|
delegate.name = newName;
|
||||||
|
delegate.commitTime = newCommitTime;
|
||||||
DelegateUpdated(idDelegate);
|
DelegateUpdated(idDelegate);
|
||||||
}
|
}
|
||||||
|
|
||||||
event DelegateUpdated(uint64 indexed idDelegate);
|
event DelegateUpdated(uint64 indexed idDelegate);
|
||||||
|
|
||||||
function addProject(string name, address projectManager, uint64 parentProject, uint64 commitTime) {
|
function addProject(string name, address projectManager, uint64 parentProject, uint64 commitTime, ILiquidPledgingPlugin plugin) returns (uint64 idProject) {
|
||||||
if (parentProject != 0) {
|
if (parentProject != 0) {
|
||||||
NoteManager storage pm = findManager(parentProject);
|
NoteManager storage pm = findManager(parentProject);
|
||||||
require(pm.managerType == NoteManagerType.Project);
|
require(pm.managerType == NoteManagerType.Project);
|
||||||
require(pm.addr == msg.sender);
|
require(pm.addr == msg.sender);
|
||||||
require(getProjectLevel(pm) < MAX_SUBPROJECT_LEVEL);
|
require(getProjectLevel(pm) < MAX_SUBPROJECT_LEVEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
idProject = uint64(managers.length);
|
||||||
|
|
||||||
managers.push(NoteManager(
|
managers.push(NoteManager(
|
||||||
NoteManagerType.Project,
|
NoteManagerType.Project,
|
||||||
projectManager,
|
projectManager,
|
||||||
name,
|
name,
|
||||||
commitTime,
|
commitTime,
|
||||||
parentProject,
|
parentProject,
|
||||||
false));
|
false,
|
||||||
|
plugin));
|
||||||
|
|
||||||
ProjectAdded(uint64(managers.length-1));
|
|
||||||
|
ProjectAdded(idProject);
|
||||||
}
|
}
|
||||||
|
|
||||||
event ProjectAdded(uint64 indexed idProject);
|
event ProjectAdded(uint64 indexed idProject);
|
||||||
|
|
||||||
function updateProject(uint64 idProject, address newAddr, string newName, uint64 newCommitTime) {
|
function updateProject(
|
||||||
|
uint64 idProject,
|
||||||
|
address newAddr,
|
||||||
|
string newName,
|
||||||
|
uint64 newCommitTime)
|
||||||
|
{
|
||||||
NoteManager storage project = findManager(idProject);
|
NoteManager storage project = findManager(idProject);
|
||||||
require(project.managerType == NoteManagerType.Project);
|
require(project.managerType == NoteManagerType.Project);
|
||||||
require(project.addr == msg.sender);
|
require(project.addr == msg.sender);
|
||||||
@ -274,6 +321,17 @@ contract LiquidPledgingBase {
|
|||||||
return getNoteLevel(oldN) + 1;
|
return getNoteLevel(oldN) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// helper function that returns the max commit time of the owner and all the
|
||||||
|
// delegates
|
||||||
|
function maxCommitTime(Note n) internal returns(uint commitTime) {
|
||||||
|
NoteManager storage m = findManager(n.owner);
|
||||||
|
commitTime = m.commitTime;
|
||||||
|
|
||||||
|
for (uint i=0; i<n.delegationChain.length; i++) {
|
||||||
|
m = findManager(n.delegationChain[i]);
|
||||||
|
if (m.commitTime > commitTime) commitTime = m.commitTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// helper function that returns the project level solely to check that there
|
// helper function that returns the project level solely to check that there
|
||||||
// are not too many Projects that violate MAX_SUBPROJECT_LEVEL
|
// are not too many Projects that violate MAX_SUBPROJECT_LEVEL
|
||||||
@ -318,4 +376,11 @@ contract LiquidPledgingBase {
|
|||||||
return getOldestNoteNotCanceled(n.oldNote);
|
return getOldestNoteNotCanceled(n.oldNote);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function checkManagerOwner(NoteManager m) internal constant {
|
||||||
|
require((msg.sender == m.addr) || (msg.sender == address(m.plugin)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
File diff suppressed because one or more lines are too long
@ -1,7 +1,30 @@
|
|||||||
|
|
||||||
|
//File: contracts/ILiquidPledgingPlugin.sol
|
||||||
|
pragma solidity ^0.4.11;
|
||||||
|
|
||||||
|
contract ILiquidPledgingPlugin {
|
||||||
|
|
||||||
|
/// @param context In which context it is affected.
|
||||||
|
/// 0 -> owner from
|
||||||
|
/// 1 -> First delegate from
|
||||||
|
/// 2 -> Second delegate from
|
||||||
|
/// ...
|
||||||
|
/// 255 -> proposedProject from
|
||||||
|
///
|
||||||
|
/// 256 -> owner to
|
||||||
|
/// 257 -> First delegate to
|
||||||
|
/// 258 -> Second delegate to
|
||||||
|
/// ...
|
||||||
|
/// 511 -> proposedProject to
|
||||||
|
function beforeTransfer(uint64 noteManager, uint64 noteFrom, uint64 noteTo, uint64 context, uint amount) returns (uint maxAllowed);
|
||||||
|
function afterTransfer(uint64 noteManager, uint64 noteFrom, uint64 noteTo, uint64 context, uint amount);
|
||||||
|
}
|
||||||
|
|
||||||
//File: contracts/LiquidPledgingBase.sol
|
//File: contracts/LiquidPledgingBase.sol
|
||||||
pragma solidity ^0.4.11;
|
pragma solidity ^0.4.11;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
contract Vault {
|
contract Vault {
|
||||||
function authorizePayment(bytes32 _ref, address _dest, uint _amount);
|
function authorizePayment(bytes32 _ref, address _dest, uint _amount);
|
||||||
function () payable;
|
function () payable;
|
||||||
@ -24,6 +47,7 @@ contract LiquidPledgingBase {
|
|||||||
uint64 commitTime; // Only used in donors and projects, its the precommitment time
|
uint64 commitTime; // Only used in donors and projects, its the precommitment time
|
||||||
uint64 parentProject; // Only for projects
|
uint64 parentProject; // Only for projects
|
||||||
bool canceled; // Only for project
|
bool canceled; // Only for project
|
||||||
|
ILiquidPledgingPlugin plugin; // Handler that is called when one call is affected.
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Note {
|
struct Note {
|
||||||
@ -69,16 +93,20 @@ contract LiquidPledgingBase {
|
|||||||
// Managers functions
|
// Managers functions
|
||||||
//////
|
//////
|
||||||
|
|
||||||
function addDonor(string name, uint64 commitTime) {//Todo return idManager
|
function addDonor(string name, uint64 commitTime, ILiquidPledgingPlugin plugin) returns (uint64 idDonor) {//Todo return idManager
|
||||||
|
|
||||||
|
idDonor = uint64(managers.length);
|
||||||
|
|
||||||
managers.push(NoteManager(
|
managers.push(NoteManager(
|
||||||
NoteManagerType.Donor,
|
NoteManagerType.Donor,
|
||||||
msg.sender,
|
msg.sender,
|
||||||
name,
|
name,
|
||||||
commitTime,
|
commitTime,
|
||||||
0,
|
0,
|
||||||
false));
|
false,
|
||||||
|
plugin));
|
||||||
|
|
||||||
DonorAdded(uint64(managers.length-1));
|
DonorAdded(idDonor);
|
||||||
}
|
}
|
||||||
|
|
||||||
event DonorAdded(uint64 indexed idDonor);
|
event DonorAdded(uint64 indexed idDonor);
|
||||||
@ -100,52 +128,71 @@ contract LiquidPledgingBase {
|
|||||||
|
|
||||||
event DonorUpdated(uint64 indexed idDonor);
|
event DonorUpdated(uint64 indexed idDonor);
|
||||||
|
|
||||||
function addDelegate(string name) { //TODO return index number
|
function addDelegate(string name, uint64 commitTime, ILiquidPledgingPlugin plugin) returns (uint64 idDelegate) { //TODO return index number
|
||||||
|
|
||||||
|
idDelegate = uint64(managers.length);
|
||||||
|
|
||||||
managers.push(NoteManager(
|
managers.push(NoteManager(
|
||||||
NoteManagerType.Delegate,
|
NoteManagerType.Delegate,
|
||||||
msg.sender,
|
msg.sender,
|
||||||
name,
|
name,
|
||||||
|
commitTime,
|
||||||
0,
|
0,
|
||||||
0,
|
false,
|
||||||
false));
|
plugin));
|
||||||
|
|
||||||
DeegateAdded(uint64(managers.length-1));
|
DeegateAdded(idDelegate);
|
||||||
}
|
}
|
||||||
|
|
||||||
event DeegateAdded(uint64 indexed idDelegate);
|
event DeegateAdded(uint64 indexed idDelegate);
|
||||||
|
|
||||||
function updateDelegate(uint64 idDelegate, address newAddr, string newName) {
|
function updateDelegate(
|
||||||
|
uint64 idDelegate,
|
||||||
|
address newAddr,
|
||||||
|
string newName,
|
||||||
|
uint64 newCommitTime) {
|
||||||
NoteManager storage delegate = findManager(idDelegate);
|
NoteManager storage delegate = findManager(idDelegate);
|
||||||
require(delegate.managerType == NoteManagerType.Delegate);
|
require(delegate.managerType == NoteManagerType.Delegate);
|
||||||
require(delegate.addr == msg.sender);
|
require(delegate.addr == msg.sender);
|
||||||
delegate.addr = newAddr;
|
delegate.addr = newAddr;
|
||||||
delegate.name = newName;
|
delegate.name = newName;
|
||||||
|
delegate.commitTime = newCommitTime;
|
||||||
DelegateUpdated(idDelegate);
|
DelegateUpdated(idDelegate);
|
||||||
}
|
}
|
||||||
|
|
||||||
event DelegateUpdated(uint64 indexed idDelegate);
|
event DelegateUpdated(uint64 indexed idDelegate);
|
||||||
|
|
||||||
function addProject(string name, address projectManager, uint64 parentProject, uint64 commitTime) {
|
function addProject(string name, address projectManager, uint64 parentProject, uint64 commitTime, ILiquidPledgingPlugin plugin) returns (uint64 idProject) {
|
||||||
if (parentProject != 0) {
|
if (parentProject != 0) {
|
||||||
NoteManager storage pm = findManager(parentProject);
|
NoteManager storage pm = findManager(parentProject);
|
||||||
require(pm.managerType == NoteManagerType.Project);
|
require(pm.managerType == NoteManagerType.Project);
|
||||||
require(pm.addr == msg.sender);
|
require(pm.addr == msg.sender);
|
||||||
require(getProjectLevel(pm) < MAX_SUBPROJECT_LEVEL);
|
require(getProjectLevel(pm) < MAX_SUBPROJECT_LEVEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
idProject = uint64(managers.length);
|
||||||
|
|
||||||
managers.push(NoteManager(
|
managers.push(NoteManager(
|
||||||
NoteManagerType.Project,
|
NoteManagerType.Project,
|
||||||
projectManager,
|
projectManager,
|
||||||
name,
|
name,
|
||||||
commitTime,
|
commitTime,
|
||||||
parentProject,
|
parentProject,
|
||||||
false));
|
false,
|
||||||
|
plugin));
|
||||||
|
|
||||||
ProjectAdded(uint64(managers.length-1));
|
|
||||||
|
ProjectAdded(idProject);
|
||||||
}
|
}
|
||||||
|
|
||||||
event ProjectAdded(uint64 indexed idProject);
|
event ProjectAdded(uint64 indexed idProject);
|
||||||
|
|
||||||
function updateProject(uint64 idProject, address newAddr, string newName, uint64 newCommitTime) {
|
function updateProject(
|
||||||
|
uint64 idProject,
|
||||||
|
address newAddr,
|
||||||
|
string newName,
|
||||||
|
uint64 newCommitTime)
|
||||||
|
{
|
||||||
NoteManager storage project = findManager(idProject);
|
NoteManager storage project = findManager(idProject);
|
||||||
require(project.managerType == NoteManagerType.Project);
|
require(project.managerType == NoteManagerType.Project);
|
||||||
require(project.addr == msg.sender);
|
require(project.addr == msg.sender);
|
||||||
@ -274,6 +321,17 @@ contract LiquidPledgingBase {
|
|||||||
return getNoteLevel(oldN) + 1;
|
return getNoteLevel(oldN) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// helper function that returns the max commit time of the owner and all the
|
||||||
|
// delegates
|
||||||
|
function maxCommitTime(Note n) internal returns(uint commitTime) {
|
||||||
|
NoteManager storage m = findManager(n.owner);
|
||||||
|
commitTime = m.commitTime;
|
||||||
|
|
||||||
|
for (uint i=0; i<n.delegationChain.length; i++) {
|
||||||
|
m = findManager(n.delegationChain[i]);
|
||||||
|
if (m.commitTime > commitTime) commitTime = m.commitTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// helper function that returns the project level solely to check that there
|
// helper function that returns the project level solely to check that there
|
||||||
// are not too many Projects that violate MAX_SUBPROJECT_LEVEL
|
// are not too many Projects that violate MAX_SUBPROJECT_LEVEL
|
||||||
@ -318,6 +376,13 @@ contract LiquidPledgingBase {
|
|||||||
return getOldestNoteNotCanceled(n.oldNote);
|
return getOldestNoteNotCanceled(n.oldNote);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function checkManagerOwner(NoteManager m) internal constant {
|
||||||
|
require((msg.sender == m.addr) || (msg.sender == address(m.plugin)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//File: contracts/LiquidPledging.sol
|
//File: contracts/LiquidPledging.sol
|
||||||
@ -348,8 +413,9 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
function donate(uint64 idDonor, uint64 idReceiver) payable {// TODO change to `pledge()`
|
function donate(uint64 idDonor, uint64 idReceiver) payable {// TODO change to `pledge()`
|
||||||
NoteManager storage sender = findManager(idDonor);
|
NoteManager storage sender = findManager(idDonor);
|
||||||
|
|
||||||
|
checkManagerOwner(sender);
|
||||||
|
|
||||||
require(sender.managerType == NoteManagerType.Donor);
|
require(sender.managerType == NoteManagerType.Donor);
|
||||||
require(sender.addr == msg.sender);
|
|
||||||
|
|
||||||
uint amount = msg.value;
|
uint amount = msg.value;
|
||||||
|
|
||||||
@ -389,7 +455,7 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
NoteManager storage receiver = findManager(idReceiver);
|
NoteManager storage receiver = findManager(idReceiver);
|
||||||
NoteManager storage sender = findManager(idSender);
|
NoteManager storage sender = findManager(idSender);
|
||||||
|
|
||||||
require(sender.addr == msg.sender);
|
checkManagerOwner(sender);
|
||||||
require(n.paymentState == PaymentState.NotPaid);
|
require(n.paymentState == PaymentState.NotPaid);
|
||||||
|
|
||||||
// If the sender is the owner
|
// If the sender is the owner
|
||||||
@ -472,7 +538,7 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
|
|
||||||
NoteManager storage owner = findManager(n.owner);
|
NoteManager storage owner = findManager(n.owner);
|
||||||
|
|
||||||
require(owner.addr == msg.sender);
|
checkManagerOwner(owner);
|
||||||
|
|
||||||
uint64 idNewNote = findNote(
|
uint64 idNewNote = findNote(
|
||||||
n.owner,
|
n.owner,
|
||||||
@ -538,10 +604,23 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
/// @param idProject Id of the projct that wants to be canceled.
|
/// @param idProject Id of the projct that wants to be canceled.
|
||||||
function cancelProject(uint64 idProject) {
|
function cancelProject(uint64 idProject) {
|
||||||
NoteManager storage project = findManager(idProject);
|
NoteManager storage project = findManager(idProject);
|
||||||
require(project.addr == msg.sender);
|
checkManagerOwner(project);
|
||||||
project.canceled = true;
|
project.canceled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function cancelNote(uint64 idNote, uint amount) {
|
||||||
|
idNote = normalizeNote(idNote);
|
||||||
|
|
||||||
|
Note storage n = findNote(idNote);
|
||||||
|
|
||||||
|
NoteManager storage m = findManager(n.owner);
|
||||||
|
checkManagerOwner(m);
|
||||||
|
|
||||||
|
doTransfer(idNote, n.oldNote, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////
|
////////
|
||||||
// Multi note methods
|
// Multi note methods
|
||||||
////////
|
////////
|
||||||
@ -585,6 +664,14 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mNormalizeNote(uint[] notes) returns(uint64) {
|
||||||
|
for (uint i = 0; i < notes.length; i++ ) {
|
||||||
|
uint64 idNote = uint64( notes[i] & (D64-1) );
|
||||||
|
|
||||||
|
normalizeNote(idNote);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////
|
////////
|
||||||
// Private methods
|
// Private methods
|
||||||
///////
|
///////
|
||||||
@ -613,8 +700,6 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function transferOwnershipToDonor(uint64 idNote, uint amount, uint64 idReceiver) internal {
|
function transferOwnershipToDonor(uint64 idNote, uint amount, uint64 idReceiver) internal {
|
||||||
Note storage n = findNote(idNote);
|
|
||||||
|
|
||||||
uint64 toNote = findNote(
|
uint64 toNote = findNote(
|
||||||
idReceiver,
|
idReceiver,
|
||||||
new uint64[](0),
|
new uint64[](0),
|
||||||
@ -670,18 +755,18 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
|
|
||||||
require(getNoteLevel(n) < MAX_SUBPROJECT_LEVEL);
|
require(getNoteLevel(n) < MAX_SUBPROJECT_LEVEL);
|
||||||
|
|
||||||
NoteManager storage owner = findManager(n.owner);
|
|
||||||
uint64 toNote = findNote(
|
uint64 toNote = findNote(
|
||||||
n.owner,
|
n.owner,
|
||||||
n.delegationChain,
|
n.delegationChain,
|
||||||
idReceiver,
|
idReceiver,
|
||||||
uint64(getTime() + owner.commitTime),
|
uint64(getTime() + maxCommitTime(n)),
|
||||||
n.oldNote,
|
n.oldNote,
|
||||||
PaymentState.NotPaid);
|
PaymentState.NotPaid);
|
||||||
doTransfer(idNote, toNote, amount);
|
doTransfer(idNote, toNote, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
function doTransfer(uint64 from, uint64 to, uint amount) internal {
|
function doTransfer(uint64 from, uint64 to, uint _amount) internal {
|
||||||
|
uint amount = callPlugins(true, from, to, _amount);
|
||||||
if (from == to) return;
|
if (from == to) return;
|
||||||
if (amount == 0) return;
|
if (amount == 0) return;
|
||||||
Note storage nFrom = findNote(from);
|
Note storage nFrom = findNote(from);
|
||||||
@ -691,6 +776,7 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
nTo.amount += amount;
|
nTo.amount += amount;
|
||||||
|
|
||||||
Transfer(from, to, amount);
|
Transfer(from, to, amount);
|
||||||
|
callPlugins(false, from, to, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function does 2 things, #1: it checks to make sure that the pledges are correct
|
// This function does 2 things, #1: it checks to make sure that the pledges are correct
|
||||||
@ -699,7 +785,9 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
// do what this function does to the note for the end user at the expiration of the committime)
|
// do what this function does to the note for the end user at the expiration of the committime)
|
||||||
// #2: It checks to make sure that if there has been a cancellation in the chain of projects,
|
// #2: It checks to make sure that if there has been a cancellation in the chain of projects,
|
||||||
// then it adjusts the note's owner appropriately.
|
// then it adjusts the note's owner appropriately.
|
||||||
function normalizeNote(uint64 idNote) internal returns(uint64) {
|
// This call can be called from any body at any time on any node. In general it can be called
|
||||||
|
// to froce the calls of the affected plugins.
|
||||||
|
function normalizeNote(uint64 idNote) returns(uint64) {
|
||||||
Note storage n = findNote(idNote);
|
Note storage n = findNote(idNote);
|
||||||
|
|
||||||
// Check to make sure this note hasnt already been used or is in the process of being used
|
// Check to make sure this note hasnt already been used or is in the process of being used
|
||||||
@ -734,6 +822,48 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
return toNote;
|
return toNote;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////
|
||||||
|
// Plugins
|
||||||
|
/////////////
|
||||||
|
|
||||||
|
function callPlugin(bool before, uint64 managerId, uint64 fromNote, uint64 toNote, uint64 context, uint amount) internal returns (uint allowedAmount) {
|
||||||
|
uint newAmount;
|
||||||
|
allowedAmount = amount;
|
||||||
|
NoteManager storage manager = findManager(managerId);
|
||||||
|
if ((address(manager.plugin) != 0) && (allowedAmount > 0)) {
|
||||||
|
if (before) {
|
||||||
|
newAmount = manager.plugin.beforeTransfer(managerId, fromNote, toNote, context, amount);
|
||||||
|
require(newAmount <= allowedAmount);
|
||||||
|
allowedAmount = newAmount;
|
||||||
|
} else {
|
||||||
|
manager.plugin.afterTransfer(managerId, fromNote, toNote, context, amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function callPluginsNote(bool before, uint64 idNote, uint64 fromNote, uint64 toNote, uint amount) internal returns (uint allowedAmount) {
|
||||||
|
uint64 offset = idNote == fromNote ? 0 : 256;
|
||||||
|
allowedAmount = amount;
|
||||||
|
Note storage n = findNote(idNote);
|
||||||
|
|
||||||
|
allowedAmount = callPlugin(before, n.owner, fromNote, toNote, offset, allowedAmount);
|
||||||
|
|
||||||
|
for (uint64 i=0; i<n.delegationChain.length; i++) {
|
||||||
|
allowedAmount = callPlugin(before, n.delegationChain[i], fromNote, toNote, offset + i+1, allowedAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n.proposedProject > 0) {
|
||||||
|
allowedAmount = callPlugin(before, n.proposedProject, fromNote, toNote, offset + 255, allowedAmount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function callPlugins(bool before, uint64 fromNote, uint64 toNote, uint amount) internal returns (uint allowedAmount) {
|
||||||
|
allowedAmount = amount;
|
||||||
|
|
||||||
|
allowedAmount = callPluginsNote(before, fromNote, fromNote, toNote, allowedAmount);
|
||||||
|
allowedAmount = callPluginsNote(before, toNote, fromNote, toNote, allowedAmount);
|
||||||
|
}
|
||||||
|
|
||||||
/////////////
|
/////////////
|
||||||
// Test functions
|
// Test functions
|
||||||
/////////////
|
/////////////
|
||||||
|
@ -1,7 +1,30 @@
|
|||||||
|
|
||||||
|
//File: contracts/ILiquidPledgingPlugin.sol
|
||||||
|
pragma solidity ^0.4.11;
|
||||||
|
|
||||||
|
contract ILiquidPledgingPlugin {
|
||||||
|
|
||||||
|
/// @param context In which context it is affected.
|
||||||
|
/// 0 -> owner from
|
||||||
|
/// 1 -> First delegate from
|
||||||
|
/// 2 -> Second delegate from
|
||||||
|
/// ...
|
||||||
|
/// 255 -> proposedProject from
|
||||||
|
///
|
||||||
|
/// 256 -> owner to
|
||||||
|
/// 257 -> First delegate to
|
||||||
|
/// 258 -> Second delegate to
|
||||||
|
/// ...
|
||||||
|
/// 511 -> proposedProject to
|
||||||
|
function beforeTransfer(uint64 noteManager, uint64 noteFrom, uint64 noteTo, uint64 context, uint amount) returns (uint maxAllowed);
|
||||||
|
function afterTransfer(uint64 noteManager, uint64 noteFrom, uint64 noteTo, uint64 context, uint amount);
|
||||||
|
}
|
||||||
|
|
||||||
//File: contracts/LiquidPledgingBase.sol
|
//File: contracts/LiquidPledgingBase.sol
|
||||||
pragma solidity ^0.4.11;
|
pragma solidity ^0.4.11;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
contract Vault {
|
contract Vault {
|
||||||
function authorizePayment(bytes32 _ref, address _dest, uint _amount);
|
function authorizePayment(bytes32 _ref, address _dest, uint _amount);
|
||||||
function () payable;
|
function () payable;
|
||||||
@ -24,6 +47,7 @@ contract LiquidPledgingBase {
|
|||||||
uint64 commitTime; // Only used in donors and projects, its the precommitment time
|
uint64 commitTime; // Only used in donors and projects, its the precommitment time
|
||||||
uint64 parentProject; // Only for projects
|
uint64 parentProject; // Only for projects
|
||||||
bool canceled; // Only for project
|
bool canceled; // Only for project
|
||||||
|
ILiquidPledgingPlugin plugin; // Handler that is called when one call is affected.
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Note {
|
struct Note {
|
||||||
@ -69,16 +93,20 @@ contract LiquidPledgingBase {
|
|||||||
// Managers functions
|
// Managers functions
|
||||||
//////
|
//////
|
||||||
|
|
||||||
function addDonor(string name, uint64 commitTime) {//Todo return idManager
|
function addDonor(string name, uint64 commitTime, ILiquidPledgingPlugin plugin) returns (uint64 idDonor) {//Todo return idManager
|
||||||
|
|
||||||
|
idDonor = uint64(managers.length);
|
||||||
|
|
||||||
managers.push(NoteManager(
|
managers.push(NoteManager(
|
||||||
NoteManagerType.Donor,
|
NoteManagerType.Donor,
|
||||||
msg.sender,
|
msg.sender,
|
||||||
name,
|
name,
|
||||||
commitTime,
|
commitTime,
|
||||||
0,
|
0,
|
||||||
false));
|
false,
|
||||||
|
plugin));
|
||||||
|
|
||||||
DonorAdded(uint64(managers.length-1));
|
DonorAdded(idDonor);
|
||||||
}
|
}
|
||||||
|
|
||||||
event DonorAdded(uint64 indexed idDonor);
|
event DonorAdded(uint64 indexed idDonor);
|
||||||
@ -100,52 +128,71 @@ contract LiquidPledgingBase {
|
|||||||
|
|
||||||
event DonorUpdated(uint64 indexed idDonor);
|
event DonorUpdated(uint64 indexed idDonor);
|
||||||
|
|
||||||
function addDelegate(string name) { //TODO return index number
|
function addDelegate(string name, uint64 commitTime, ILiquidPledgingPlugin plugin) returns (uint64 idDelegate) { //TODO return index number
|
||||||
|
|
||||||
|
idDelegate = uint64(managers.length);
|
||||||
|
|
||||||
managers.push(NoteManager(
|
managers.push(NoteManager(
|
||||||
NoteManagerType.Delegate,
|
NoteManagerType.Delegate,
|
||||||
msg.sender,
|
msg.sender,
|
||||||
name,
|
name,
|
||||||
|
commitTime,
|
||||||
0,
|
0,
|
||||||
0,
|
false,
|
||||||
false));
|
plugin));
|
||||||
|
|
||||||
DeegateAdded(uint64(managers.length-1));
|
DeegateAdded(idDelegate);
|
||||||
}
|
}
|
||||||
|
|
||||||
event DeegateAdded(uint64 indexed idDelegate);
|
event DeegateAdded(uint64 indexed idDelegate);
|
||||||
|
|
||||||
function updateDelegate(uint64 idDelegate, address newAddr, string newName) {
|
function updateDelegate(
|
||||||
|
uint64 idDelegate,
|
||||||
|
address newAddr,
|
||||||
|
string newName,
|
||||||
|
uint64 newCommitTime) {
|
||||||
NoteManager storage delegate = findManager(idDelegate);
|
NoteManager storage delegate = findManager(idDelegate);
|
||||||
require(delegate.managerType == NoteManagerType.Delegate);
|
require(delegate.managerType == NoteManagerType.Delegate);
|
||||||
require(delegate.addr == msg.sender);
|
require(delegate.addr == msg.sender);
|
||||||
delegate.addr = newAddr;
|
delegate.addr = newAddr;
|
||||||
delegate.name = newName;
|
delegate.name = newName;
|
||||||
|
delegate.commitTime = newCommitTime;
|
||||||
DelegateUpdated(idDelegate);
|
DelegateUpdated(idDelegate);
|
||||||
}
|
}
|
||||||
|
|
||||||
event DelegateUpdated(uint64 indexed idDelegate);
|
event DelegateUpdated(uint64 indexed idDelegate);
|
||||||
|
|
||||||
function addProject(string name, address projectManager, uint64 parentProject, uint64 commitTime) {
|
function addProject(string name, address projectManager, uint64 parentProject, uint64 commitTime, ILiquidPledgingPlugin plugin) returns (uint64 idProject) {
|
||||||
if (parentProject != 0) {
|
if (parentProject != 0) {
|
||||||
NoteManager storage pm = findManager(parentProject);
|
NoteManager storage pm = findManager(parentProject);
|
||||||
require(pm.managerType == NoteManagerType.Project);
|
require(pm.managerType == NoteManagerType.Project);
|
||||||
require(pm.addr == msg.sender);
|
require(pm.addr == msg.sender);
|
||||||
require(getProjectLevel(pm) < MAX_SUBPROJECT_LEVEL);
|
require(getProjectLevel(pm) < MAX_SUBPROJECT_LEVEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
idProject = uint64(managers.length);
|
||||||
|
|
||||||
managers.push(NoteManager(
|
managers.push(NoteManager(
|
||||||
NoteManagerType.Project,
|
NoteManagerType.Project,
|
||||||
projectManager,
|
projectManager,
|
||||||
name,
|
name,
|
||||||
commitTime,
|
commitTime,
|
||||||
parentProject,
|
parentProject,
|
||||||
false));
|
false,
|
||||||
|
plugin));
|
||||||
|
|
||||||
ProjectAdded(uint64(managers.length-1));
|
|
||||||
|
ProjectAdded(idProject);
|
||||||
}
|
}
|
||||||
|
|
||||||
event ProjectAdded(uint64 indexed idProject);
|
event ProjectAdded(uint64 indexed idProject);
|
||||||
|
|
||||||
function updateProject(uint64 idProject, address newAddr, string newName, uint64 newCommitTime) {
|
function updateProject(
|
||||||
|
uint64 idProject,
|
||||||
|
address newAddr,
|
||||||
|
string newName,
|
||||||
|
uint64 newCommitTime)
|
||||||
|
{
|
||||||
NoteManager storage project = findManager(idProject);
|
NoteManager storage project = findManager(idProject);
|
||||||
require(project.managerType == NoteManagerType.Project);
|
require(project.managerType == NoteManagerType.Project);
|
||||||
require(project.addr == msg.sender);
|
require(project.addr == msg.sender);
|
||||||
@ -274,6 +321,17 @@ contract LiquidPledgingBase {
|
|||||||
return getNoteLevel(oldN) + 1;
|
return getNoteLevel(oldN) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// helper function that returns the max commit time of the owner and all the
|
||||||
|
// delegates
|
||||||
|
function maxCommitTime(Note n) internal returns(uint commitTime) {
|
||||||
|
NoteManager storage m = findManager(n.owner);
|
||||||
|
commitTime = m.commitTime;
|
||||||
|
|
||||||
|
for (uint i=0; i<n.delegationChain.length; i++) {
|
||||||
|
m = findManager(n.delegationChain[i]);
|
||||||
|
if (m.commitTime > commitTime) commitTime = m.commitTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// helper function that returns the project level solely to check that there
|
// helper function that returns the project level solely to check that there
|
||||||
// are not too many Projects that violate MAX_SUBPROJECT_LEVEL
|
// are not too many Projects that violate MAX_SUBPROJECT_LEVEL
|
||||||
@ -318,6 +376,13 @@ contract LiquidPledgingBase {
|
|||||||
return getOldestNoteNotCanceled(n.oldNote);
|
return getOldestNoteNotCanceled(n.oldNote);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function checkManagerOwner(NoteManager m) internal constant {
|
||||||
|
require((msg.sender == m.addr) || (msg.sender == address(m.plugin)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//File: ./contracts/LiquidPledging.sol
|
//File: ./contracts/LiquidPledging.sol
|
||||||
@ -348,8 +413,9 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
function donate(uint64 idDonor, uint64 idReceiver) payable {// TODO change to `pledge()`
|
function donate(uint64 idDonor, uint64 idReceiver) payable {// TODO change to `pledge()`
|
||||||
NoteManager storage sender = findManager(idDonor);
|
NoteManager storage sender = findManager(idDonor);
|
||||||
|
|
||||||
|
checkManagerOwner(sender);
|
||||||
|
|
||||||
require(sender.managerType == NoteManagerType.Donor);
|
require(sender.managerType == NoteManagerType.Donor);
|
||||||
require(sender.addr == msg.sender);
|
|
||||||
|
|
||||||
uint amount = msg.value;
|
uint amount = msg.value;
|
||||||
|
|
||||||
@ -389,7 +455,7 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
NoteManager storage receiver = findManager(idReceiver);
|
NoteManager storage receiver = findManager(idReceiver);
|
||||||
NoteManager storage sender = findManager(idSender);
|
NoteManager storage sender = findManager(idSender);
|
||||||
|
|
||||||
require(sender.addr == msg.sender);
|
checkManagerOwner(sender);
|
||||||
require(n.paymentState == PaymentState.NotPaid);
|
require(n.paymentState == PaymentState.NotPaid);
|
||||||
|
|
||||||
// If the sender is the owner
|
// If the sender is the owner
|
||||||
@ -472,7 +538,7 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
|
|
||||||
NoteManager storage owner = findManager(n.owner);
|
NoteManager storage owner = findManager(n.owner);
|
||||||
|
|
||||||
require(owner.addr == msg.sender);
|
checkManagerOwner(owner);
|
||||||
|
|
||||||
uint64 idNewNote = findNote(
|
uint64 idNewNote = findNote(
|
||||||
n.owner,
|
n.owner,
|
||||||
@ -538,10 +604,23 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
/// @param idProject Id of the projct that wants to be canceled.
|
/// @param idProject Id of the projct that wants to be canceled.
|
||||||
function cancelProject(uint64 idProject) {
|
function cancelProject(uint64 idProject) {
|
||||||
NoteManager storage project = findManager(idProject);
|
NoteManager storage project = findManager(idProject);
|
||||||
require(project.addr == msg.sender);
|
checkManagerOwner(project);
|
||||||
project.canceled = true;
|
project.canceled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function cancelNote(uint64 idNote, uint amount) {
|
||||||
|
idNote = normalizeNote(idNote);
|
||||||
|
|
||||||
|
Note storage n = findNote(idNote);
|
||||||
|
|
||||||
|
NoteManager storage m = findManager(n.owner);
|
||||||
|
checkManagerOwner(m);
|
||||||
|
|
||||||
|
doTransfer(idNote, n.oldNote, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////
|
////////
|
||||||
// Multi note methods
|
// Multi note methods
|
||||||
////////
|
////////
|
||||||
@ -585,6 +664,14 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mNormalizeNote(uint[] notes) returns(uint64) {
|
||||||
|
for (uint i = 0; i < notes.length; i++ ) {
|
||||||
|
uint64 idNote = uint64( notes[i] & (D64-1) );
|
||||||
|
|
||||||
|
normalizeNote(idNote);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////
|
////////
|
||||||
// Private methods
|
// Private methods
|
||||||
///////
|
///////
|
||||||
@ -613,8 +700,6 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function transferOwnershipToDonor(uint64 idNote, uint amount, uint64 idReceiver) internal {
|
function transferOwnershipToDonor(uint64 idNote, uint amount, uint64 idReceiver) internal {
|
||||||
Note storage n = findNote(idNote);
|
|
||||||
|
|
||||||
uint64 toNote = findNote(
|
uint64 toNote = findNote(
|
||||||
idReceiver,
|
idReceiver,
|
||||||
new uint64[](0),
|
new uint64[](0),
|
||||||
@ -670,18 +755,18 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
|
|
||||||
require(getNoteLevel(n) < MAX_SUBPROJECT_LEVEL);
|
require(getNoteLevel(n) < MAX_SUBPROJECT_LEVEL);
|
||||||
|
|
||||||
NoteManager storage owner = findManager(n.owner);
|
|
||||||
uint64 toNote = findNote(
|
uint64 toNote = findNote(
|
||||||
n.owner,
|
n.owner,
|
||||||
n.delegationChain,
|
n.delegationChain,
|
||||||
idReceiver,
|
idReceiver,
|
||||||
uint64(getTime() + owner.commitTime),
|
uint64(getTime() + maxCommitTime(n)),
|
||||||
n.oldNote,
|
n.oldNote,
|
||||||
PaymentState.NotPaid);
|
PaymentState.NotPaid);
|
||||||
doTransfer(idNote, toNote, amount);
|
doTransfer(idNote, toNote, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
function doTransfer(uint64 from, uint64 to, uint amount) internal {
|
function doTransfer(uint64 from, uint64 to, uint _amount) internal {
|
||||||
|
uint amount = callPlugins(true, from, to, _amount);
|
||||||
if (from == to) return;
|
if (from == to) return;
|
||||||
if (amount == 0) return;
|
if (amount == 0) return;
|
||||||
Note storage nFrom = findNote(from);
|
Note storage nFrom = findNote(from);
|
||||||
@ -691,6 +776,7 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
nTo.amount += amount;
|
nTo.amount += amount;
|
||||||
|
|
||||||
Transfer(from, to, amount);
|
Transfer(from, to, amount);
|
||||||
|
callPlugins(false, from, to, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function does 2 things, #1: it checks to make sure that the pledges are correct
|
// This function does 2 things, #1: it checks to make sure that the pledges are correct
|
||||||
@ -699,7 +785,9 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
// do what this function does to the note for the end user at the expiration of the committime)
|
// do what this function does to the note for the end user at the expiration of the committime)
|
||||||
// #2: It checks to make sure that if there has been a cancellation in the chain of projects,
|
// #2: It checks to make sure that if there has been a cancellation in the chain of projects,
|
||||||
// then it adjusts the note's owner appropriately.
|
// then it adjusts the note's owner appropriately.
|
||||||
function normalizeNote(uint64 idNote) internal returns(uint64) {
|
// This call can be called from any body at any time on any node. In general it can be called
|
||||||
|
// to froce the calls of the affected plugins.
|
||||||
|
function normalizeNote(uint64 idNote) returns(uint64) {
|
||||||
Note storage n = findNote(idNote);
|
Note storage n = findNote(idNote);
|
||||||
|
|
||||||
// Check to make sure this note hasnt already been used or is in the process of being used
|
// Check to make sure this note hasnt already been used or is in the process of being used
|
||||||
@ -734,6 +822,48 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
return toNote;
|
return toNote;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////
|
||||||
|
// Plugins
|
||||||
|
/////////////
|
||||||
|
|
||||||
|
function callPlugin(bool before, uint64 managerId, uint64 fromNote, uint64 toNote, uint64 context, uint amount) internal returns (uint allowedAmount) {
|
||||||
|
uint newAmount;
|
||||||
|
allowedAmount = amount;
|
||||||
|
NoteManager storage manager = findManager(managerId);
|
||||||
|
if ((address(manager.plugin) != 0) && (allowedAmount > 0)) {
|
||||||
|
if (before) {
|
||||||
|
newAmount = manager.plugin.beforeTransfer(managerId, fromNote, toNote, context, amount);
|
||||||
|
require(newAmount <= allowedAmount);
|
||||||
|
allowedAmount = newAmount;
|
||||||
|
} else {
|
||||||
|
manager.plugin.afterTransfer(managerId, fromNote, toNote, context, amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function callPluginsNote(bool before, uint64 idNote, uint64 fromNote, uint64 toNote, uint amount) internal returns (uint allowedAmount) {
|
||||||
|
uint64 offset = idNote == fromNote ? 0 : 256;
|
||||||
|
allowedAmount = amount;
|
||||||
|
Note storage n = findNote(idNote);
|
||||||
|
|
||||||
|
allowedAmount = callPlugin(before, n.owner, fromNote, toNote, offset, allowedAmount);
|
||||||
|
|
||||||
|
for (uint64 i=0; i<n.delegationChain.length; i++) {
|
||||||
|
allowedAmount = callPlugin(before, n.delegationChain[i], fromNote, toNote, offset + i+1, allowedAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n.proposedProject > 0) {
|
||||||
|
allowedAmount = callPlugin(before, n.proposedProject, fromNote, toNote, offset + 255, allowedAmount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function callPlugins(bool before, uint64 fromNote, uint64 toNote, uint amount) internal returns (uint allowedAmount) {
|
||||||
|
allowedAmount = amount;
|
||||||
|
|
||||||
|
allowedAmount = callPluginsNote(before, fromNote, fromNote, toNote, allowedAmount);
|
||||||
|
allowedAmount = callPluginsNote(before, toNote, fromNote, toNote, allowedAmount);
|
||||||
|
}
|
||||||
|
|
||||||
/////////////
|
/////////////
|
||||||
// Test functions
|
// Test functions
|
||||||
/////////////
|
/////////////
|
||||||
|
@ -1,74 +0,0 @@
|
|||||||
pragma solidity ^0.4.11;
|
|
||||||
|
|
||||||
contract ILiquidPledging {
|
|
||||||
|
|
||||||
// TODO: make this enum its own contract... or at least make it so that an owner
|
|
||||||
// can add a new NoteManagerType
|
|
||||||
enum NoteManagerType { Donor, Delegate, Project}
|
|
||||||
enum PaymentState {NotPaid, Paying, Paid}
|
|
||||||
|
|
||||||
function numberOfNotes() constant returns (uint);
|
|
||||||
|
|
||||||
function getNote(uint64 idNote) constant returns(
|
|
||||||
uint amount,
|
|
||||||
uint64 owner,
|
|
||||||
uint64 nDelegates,
|
|
||||||
uint64 proposedProject,
|
|
||||||
uint64 commmitTime,
|
|
||||||
uint64 oldNote,
|
|
||||||
PaymentState paymentState
|
|
||||||
);
|
|
||||||
|
|
||||||
function getNoteDelegate(uint64 idNote, uint idxDelegate) constant returns(
|
|
||||||
uint64 idDelegate,
|
|
||||||
address addr,
|
|
||||||
string name
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
function numberOfNoteManagers() constant returns(uint);
|
|
||||||
|
|
||||||
function getNoteManager(uint64 idManager) constant returns (
|
|
||||||
NoteManagerType managerType,
|
|
||||||
address addr,
|
|
||||||
string name,
|
|
||||||
uint64 commitTime,
|
|
||||||
address reviewer,
|
|
||||||
bool canceled);
|
|
||||||
|
|
||||||
event DonorAdded(uint64 indexed idMember);
|
|
||||||
|
|
||||||
function addDonor(string name, uint64 commitTime);
|
|
||||||
function updateDonor(
|
|
||||||
uint64 idDonor,
|
|
||||||
address newAddr,
|
|
||||||
string newName,
|
|
||||||
uint64 newCommitTime);
|
|
||||||
|
|
||||||
function addDelegate(string name);
|
|
||||||
function updateDelegate(uint64 idDelegate, address newAddr, string newName);
|
|
||||||
|
|
||||||
function addProject(string name, address canceler, uint64 commitTime) ;
|
|
||||||
function updateProject(uint64 idProject, address newAddr, string newName, uint64 newCommitTime);
|
|
||||||
function updateProjectCanceler(uint64 idProject, address newCanceler);
|
|
||||||
|
|
||||||
function donate(uint64 idDonor, uint64 idReceiver) payable;
|
|
||||||
|
|
||||||
/// @param idSender idDonor or idDelegate that executes the action
|
|
||||||
/// @param idReceiver idDonor or idCampaign that wants to be transfered.
|
|
||||||
/// @param note piece That wants to be transfered.
|
|
||||||
/// @param amount quantity of the state that wants to be transfered.
|
|
||||||
function transfer(uint64 idSender, uint64 note, uint amount, uint64 idReceiver);
|
|
||||||
function mTransfer(uint64 idSender, uint[] notesAmounts, uint64 idReceiver);
|
|
||||||
|
|
||||||
function withdraw(uint64 note, uint amount, string concept);
|
|
||||||
function mWithdraw(uint[] notesAmounts, string concept);
|
|
||||||
|
|
||||||
function confirmPayment(uint64 idNote, uint amount);
|
|
||||||
function mConfirmPayment(uint[] notesAmounts);
|
|
||||||
|
|
||||||
function cancelPayment(uint64 idNote, uint amount);
|
|
||||||
function mCancelPayment(uint[] notesAmounts);
|
|
||||||
|
|
||||||
function cancelProject(int64 idCampaign);
|
|
||||||
}
|
|
19
contracts/ILiquidPledgingPlugin.sol
Normal file
19
contracts/ILiquidPledgingPlugin.sol
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
pragma solidity ^0.4.11;
|
||||||
|
|
||||||
|
contract ILiquidPledgingPlugin {
|
||||||
|
|
||||||
|
/// @param context In which context it is affected.
|
||||||
|
/// 0 -> owner from
|
||||||
|
/// 1 -> First delegate from
|
||||||
|
/// 2 -> Second delegate from
|
||||||
|
/// ...
|
||||||
|
/// 255 -> proposedProject from
|
||||||
|
///
|
||||||
|
/// 256 -> owner to
|
||||||
|
/// 257 -> First delegate to
|
||||||
|
/// 258 -> Second delegate to
|
||||||
|
/// ...
|
||||||
|
/// 511 -> proposedProject to
|
||||||
|
function beforeTransfer(uint64 noteManager, uint64 noteFrom, uint64 noteTo, uint64 context, uint amount) returns (uint maxAllowed);
|
||||||
|
function afterTransfer(uint64 noteManager, uint64 noteFrom, uint64 noteTo, uint64 context, uint amount);
|
||||||
|
}
|
@ -1,74 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
contract LiquidPledgingInterface {
|
|
||||||
|
|
||||||
function addUser
|
|
||||||
function updateUser
|
|
||||||
function addCause
|
|
||||||
|
|
||||||
|
|
||||||
function deposit(uint64 user) payable;
|
|
||||||
|
|
||||||
function withdraw(uint64 user, uint64 idNote, uint amount);
|
|
||||||
|
|
||||||
function delegate(uint64 user, uint64 idNote, uint64 purpuse, uint amout);
|
|
||||||
function undelegate(uint64 user, uint64 idNote, uint amount);
|
|
||||||
|
|
||||||
|
|
||||||
function precommit(uint user, uint64 idNote, uint64 recipient, uint amount);
|
|
||||||
function unPrecommit(uint user, uint64 idNote, uint amount);
|
|
||||||
|
|
||||||
function transfer(uint64 user, uint64 idNote, uint64 recipient, uint amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
owner project out
|
|
||||||
owner transfer invest withdrow
|
|
||||||
project uninvest detail spend
|
|
||||||
in deposit xx xx
|
|
||||||
|
|
||||||
Who owns
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
Liquid LiquidPledging
|
|
||||||
|
|
||||||
//////
|
|
||||||
|
|
||||||
Funding part
|
|
||||||
|
|
||||||
/////
|
|
||||||
|
|
||||||
Executive part
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
contract Project {
|
|
||||||
|
|
||||||
struct TokenOwnership {
|
|
||||||
address token;
|
|
||||||
uint purchaseBlock;
|
|
||||||
uint amount;
|
|
||||||
bytes32 ref;
|
|
||||||
}
|
|
||||||
|
|
||||||
Minime2Token public projectToken;
|
|
||||||
|
|
||||||
mapping(uint => Minime2Token) public pledgedTokens;
|
|
||||||
|
|
||||||
TokenOwnership[] public ownerships;
|
|
||||||
|
|
||||||
|
|
||||||
function pledge(address investor, uint amount, uint precommit);
|
|
||||||
|
|
||||||
function unpledge(address investor, uint amount);
|
|
||||||
|
|
||||||
function invest(address investor, uint amount);
|
|
||||||
function unInvest(address investor, uint amount);
|
|
||||||
|
|
||||||
function pay(address dest, uint amount, uint block) onlyProjectManager;
|
|
||||||
function receive(uint amount);
|
|
||||||
|
|
||||||
function payDividends(uint token, uint amount, uint payBlock);
|
|
||||||
}
|
|
@ -29,8 +29,9 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
|
|
||||||
NoteManager storage sender = findManager(idDonor);
|
NoteManager storage sender = findManager(idDonor);
|
||||||
|
|
||||||
|
checkManagerOwner(sender);
|
||||||
|
|
||||||
require(sender.managerType == NoteManagerType.Donor);
|
require(sender.managerType == NoteManagerType.Donor);
|
||||||
require(sender.addr == msg.sender);
|
|
||||||
|
|
||||||
uint amount = msg.value;
|
uint amount = msg.value;
|
||||||
|
|
||||||
@ -70,7 +71,7 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
NoteManager storage receiver = findManager(idReceiver);
|
NoteManager storage receiver = findManager(idReceiver);
|
||||||
NoteManager storage sender = findManager(idSender);
|
NoteManager storage sender = findManager(idSender);
|
||||||
|
|
||||||
require(sender.addr == msg.sender);
|
checkManagerOwner(sender);
|
||||||
require(n.paymentState == PaymentState.NotPaid);
|
require(n.paymentState == PaymentState.NotPaid);
|
||||||
|
|
||||||
// If the sender is the owner
|
// If the sender is the owner
|
||||||
@ -153,7 +154,7 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
|
|
||||||
NoteManager storage owner = findManager(n.owner);
|
NoteManager storage owner = findManager(n.owner);
|
||||||
|
|
||||||
require(owner.addr == msg.sender);
|
checkManagerOwner(owner);
|
||||||
|
|
||||||
uint64 idNewNote = findNote(
|
uint64 idNewNote = findNote(
|
||||||
n.owner,
|
n.owner,
|
||||||
@ -219,10 +220,23 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
/// @param idProject Id of the projct that wants to be canceled.
|
/// @param idProject Id of the projct that wants to be canceled.
|
||||||
function cancelProject(uint64 idProject) {
|
function cancelProject(uint64 idProject) {
|
||||||
NoteManager storage project = findManager(idProject);
|
NoteManager storage project = findManager(idProject);
|
||||||
require(project.addr == msg.sender);
|
checkManagerOwner(project);
|
||||||
project.canceled = true;
|
project.canceled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function cancelNote(uint64 idNote, uint amount) {
|
||||||
|
idNote = normalizeNote(idNote);
|
||||||
|
|
||||||
|
Note storage n = findNote(idNote);
|
||||||
|
|
||||||
|
NoteManager storage m = findManager(n.owner);
|
||||||
|
checkManagerOwner(m);
|
||||||
|
|
||||||
|
doTransfer(idNote, n.oldNote, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////
|
////////
|
||||||
// Multi note methods
|
// Multi note methods
|
||||||
////////
|
////////
|
||||||
@ -266,6 +280,14 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mNormalizeNote(uint[] notes) returns(uint64) {
|
||||||
|
for (uint i = 0; i < notes.length; i++ ) {
|
||||||
|
uint64 idNote = uint64( notes[i] & (D64-1) );
|
||||||
|
|
||||||
|
normalizeNote(idNote);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////
|
////////
|
||||||
// Private methods
|
// Private methods
|
||||||
///////
|
///////
|
||||||
@ -294,8 +316,6 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function transferOwnershipToDonor(uint64 idNote, uint amount, uint64 idReceiver) internal {
|
function transferOwnershipToDonor(uint64 idNote, uint amount, uint64 idReceiver) internal {
|
||||||
Note storage n = findNote(idNote);
|
|
||||||
|
|
||||||
uint64 toNote = findNote(
|
uint64 toNote = findNote(
|
||||||
idReceiver,
|
idReceiver,
|
||||||
new uint64[](0),
|
new uint64[](0),
|
||||||
@ -351,18 +371,18 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
|
|
||||||
require(getNoteLevel(n) < MAX_SUBPROJECT_LEVEL);
|
require(getNoteLevel(n) < MAX_SUBPROJECT_LEVEL);
|
||||||
|
|
||||||
NoteManager storage owner = findManager(n.owner);
|
|
||||||
uint64 toNote = findNote(
|
uint64 toNote = findNote(
|
||||||
n.owner,
|
n.owner,
|
||||||
n.delegationChain,
|
n.delegationChain,
|
||||||
idReceiver,
|
idReceiver,
|
||||||
uint64(getTime() + owner.commitTime),
|
uint64(getTime() + maxCommitTime(n)),
|
||||||
n.oldNote,
|
n.oldNote,
|
||||||
PaymentState.NotPaid);
|
PaymentState.NotPaid);
|
||||||
doTransfer(idNote, toNote, amount);
|
doTransfer(idNote, toNote, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
function doTransfer(uint64 from, uint64 to, uint amount) internal {
|
function doTransfer(uint64 from, uint64 to, uint _amount) internal {
|
||||||
|
uint amount = callPlugins(true, from, to, _amount);
|
||||||
if (from == to) return;
|
if (from == to) return;
|
||||||
if (amount == 0) return;
|
if (amount == 0) return;
|
||||||
Note storage nFrom = findNote(from);
|
Note storage nFrom = findNote(from);
|
||||||
@ -372,6 +392,7 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
nTo.amount += amount;
|
nTo.amount += amount;
|
||||||
|
|
||||||
Transfer(from, to, amount);
|
Transfer(from, to, amount);
|
||||||
|
callPlugins(false, from, to, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function does 2 things, #1: it checks to make sure that the pledges are correct
|
// This function does 2 things, #1: it checks to make sure that the pledges are correct
|
||||||
@ -380,7 +401,9 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
// do what this function does to the note for the end user at the expiration of the committime)
|
// do what this function does to the note for the end user at the expiration of the committime)
|
||||||
// #2: It checks to make sure that if there has been a cancellation in the chain of projects,
|
// #2: It checks to make sure that if there has been a cancellation in the chain of projects,
|
||||||
// then it adjusts the note's owner appropriately.
|
// then it adjusts the note's owner appropriately.
|
||||||
function normalizeNote(uint64 idNote) internal returns(uint64) {
|
// This call can be called from any body at any time on any node. In general it can be called
|
||||||
|
// to froce the calls of the affected plugins.
|
||||||
|
function normalizeNote(uint64 idNote) returns(uint64) {
|
||||||
Note storage n = findNote(idNote);
|
Note storage n = findNote(idNote);
|
||||||
|
|
||||||
// Check to make sure this note hasnt already been used or is in the process of being used
|
// Check to make sure this note hasnt already been used or is in the process of being used
|
||||||
@ -415,6 +438,48 @@ contract LiquidPledging is LiquidPledgingBase {
|
|||||||
return toNote;
|
return toNote;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////
|
||||||
|
// Plugins
|
||||||
|
/////////////
|
||||||
|
|
||||||
|
function callPlugin(bool before, uint64 managerId, uint64 fromNote, uint64 toNote, uint64 context, uint amount) internal returns (uint allowedAmount) {
|
||||||
|
uint newAmount;
|
||||||
|
allowedAmount = amount;
|
||||||
|
NoteManager storage manager = findManager(managerId);
|
||||||
|
if ((address(manager.plugin) != 0) && (allowedAmount > 0)) {
|
||||||
|
if (before) {
|
||||||
|
newAmount = manager.plugin.beforeTransfer(managerId, fromNote, toNote, context, amount);
|
||||||
|
require(newAmount <= allowedAmount);
|
||||||
|
allowedAmount = newAmount;
|
||||||
|
} else {
|
||||||
|
manager.plugin.afterTransfer(managerId, fromNote, toNote, context, amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function callPluginsNote(bool before, uint64 idNote, uint64 fromNote, uint64 toNote, uint amount) internal returns (uint allowedAmount) {
|
||||||
|
uint64 offset = idNote == fromNote ? 0 : 256;
|
||||||
|
allowedAmount = amount;
|
||||||
|
Note storage n = findNote(idNote);
|
||||||
|
|
||||||
|
allowedAmount = callPlugin(before, n.owner, fromNote, toNote, offset, allowedAmount);
|
||||||
|
|
||||||
|
for (uint64 i=0; i<n.delegationChain.length; i++) {
|
||||||
|
allowedAmount = callPlugin(before, n.delegationChain[i], fromNote, toNote, offset + i+1, allowedAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n.proposedProject > 0) {
|
||||||
|
allowedAmount = callPlugin(before, n.proposedProject, fromNote, toNote, offset + 255, allowedAmount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function callPlugins(bool before, uint64 fromNote, uint64 toNote, uint amount) internal returns (uint allowedAmount) {
|
||||||
|
allowedAmount = amount;
|
||||||
|
|
||||||
|
allowedAmount = callPluginsNote(before, fromNote, fromNote, toNote, allowedAmount);
|
||||||
|
allowedAmount = callPluginsNote(before, toNote, fromNote, toNote, allowedAmount);
|
||||||
|
}
|
||||||
|
|
||||||
/////////////
|
/////////////
|
||||||
// Test functions
|
// Test functions
|
||||||
/////////////
|
/////////////
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
pragma solidity ^0.4.11;
|
pragma solidity ^0.4.11;
|
||||||
|
|
||||||
|
import "./ILiquidPledgingPlugin.sol";
|
||||||
|
|
||||||
contract Vault {
|
contract Vault {
|
||||||
function authorizePayment(bytes32 _ref, address _dest, uint _amount);
|
function authorizePayment(bytes32 _ref, address _dest, uint _amount);
|
||||||
function () payable;
|
function () payable;
|
||||||
@ -22,6 +24,7 @@ contract LiquidPledgingBase {
|
|||||||
uint64 commitTime; // Only used in donors and projects, its the precommitment time
|
uint64 commitTime; // Only used in donors and projects, its the precommitment time
|
||||||
uint64 parentProject; // Only for projects
|
uint64 parentProject; // Only for projects
|
||||||
bool canceled; // Only for project
|
bool canceled; // Only for project
|
||||||
|
ILiquidPledgingPlugin plugin; // Handler that is called when one call is affected.
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Note {
|
struct Note {
|
||||||
@ -67,18 +70,20 @@ contract LiquidPledgingBase {
|
|||||||
// Managers functions
|
// Managers functions
|
||||||
//////
|
//////
|
||||||
|
|
||||||
function addDonor(string name, uint64 commitTime) returns (uint64 idManager) {
|
function addDonor(string name, uint64 commitTime, ILiquidPledgingPlugin plugin) returns (uint64 idDonor) {
|
||||||
|
|
||||||
|
idDonor = uint64(managers.length);
|
||||||
|
|
||||||
managers.push(NoteManager(
|
managers.push(NoteManager(
|
||||||
NoteManagerType.Donor,
|
NoteManagerType.Donor,
|
||||||
msg.sender,
|
msg.sender,
|
||||||
name,
|
name,
|
||||||
commitTime,
|
commitTime,
|
||||||
0,
|
0,
|
||||||
false));
|
false,
|
||||||
|
plugin));
|
||||||
|
|
||||||
idManager = uint64(managers.length-1);
|
DonorAdded(idDonor);
|
||||||
|
|
||||||
DonorAdded(idManager);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
event DonorAdded(uint64 indexed idDonor);
|
event DonorAdded(uint64 indexed idDonor);
|
||||||
@ -100,52 +105,71 @@ contract LiquidPledgingBase {
|
|||||||
|
|
||||||
event DonorUpdated(uint64 indexed idDonor);
|
event DonorUpdated(uint64 indexed idDonor);
|
||||||
|
|
||||||
function addDelegate(string name) { //TODO return index number
|
function addDelegate(string name, uint64 commitTime, ILiquidPledgingPlugin plugin) returns (uint64 idDelegate) { //TODO return index number
|
||||||
|
|
||||||
|
idDelegate = uint64(managers.length);
|
||||||
|
|
||||||
managers.push(NoteManager(
|
managers.push(NoteManager(
|
||||||
NoteManagerType.Delegate,
|
NoteManagerType.Delegate,
|
||||||
msg.sender,
|
msg.sender,
|
||||||
name,
|
name,
|
||||||
|
commitTime,
|
||||||
0,
|
0,
|
||||||
0,
|
false,
|
||||||
false));
|
plugin));
|
||||||
|
|
||||||
DelegateAdded(uint64(managers.length-1));
|
DelegateAdded(idDelegate);
|
||||||
}
|
}
|
||||||
|
|
||||||
event DelegateAdded(uint64 indexed idDelegate);
|
event DelegateAdded(uint64 indexed idDelegate);
|
||||||
|
|
||||||
function updateDelegate(uint64 idDelegate, address newAddr, string newName) {
|
function updateDelegate(
|
||||||
|
uint64 idDelegate,
|
||||||
|
address newAddr,
|
||||||
|
string newName,
|
||||||
|
uint64 newCommitTime) {
|
||||||
NoteManager storage delegate = findManager(idDelegate);
|
NoteManager storage delegate = findManager(idDelegate);
|
||||||
require(delegate.managerType == NoteManagerType.Delegate);
|
require(delegate.managerType == NoteManagerType.Delegate);
|
||||||
require(delegate.addr == msg.sender);
|
require(delegate.addr == msg.sender);
|
||||||
delegate.addr = newAddr;
|
delegate.addr = newAddr;
|
||||||
delegate.name = newName;
|
delegate.name = newName;
|
||||||
|
delegate.commitTime = newCommitTime;
|
||||||
DelegateUpdated(idDelegate);
|
DelegateUpdated(idDelegate);
|
||||||
}
|
}
|
||||||
|
|
||||||
event DelegateUpdated(uint64 indexed idDelegate);
|
event DelegateUpdated(uint64 indexed idDelegate);
|
||||||
|
|
||||||
function addProject(string name, address projectManager, uint64 parentProject, uint64 commitTime) {
|
function addProject(string name, address projectManager, uint64 parentProject, uint64 commitTime, ILiquidPledgingPlugin plugin) returns (uint64 idProject) {
|
||||||
if (parentProject != 0) {
|
if (parentProject != 0) {
|
||||||
NoteManager storage pm = findManager(parentProject);
|
NoteManager storage pm = findManager(parentProject);
|
||||||
require(pm.managerType == NoteManagerType.Project);
|
require(pm.managerType == NoteManagerType.Project);
|
||||||
require(pm.addr == msg.sender);
|
require(pm.addr == msg.sender);
|
||||||
require(getProjectLevel(pm) < MAX_SUBPROJECT_LEVEL);
|
require(getProjectLevel(pm) < MAX_SUBPROJECT_LEVEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
idProject = uint64(managers.length);
|
||||||
|
|
||||||
managers.push(NoteManager(
|
managers.push(NoteManager(
|
||||||
NoteManagerType.Project,
|
NoteManagerType.Project,
|
||||||
projectManager,
|
projectManager,
|
||||||
name,
|
name,
|
||||||
commitTime,
|
commitTime,
|
||||||
parentProject,
|
parentProject,
|
||||||
false));
|
false,
|
||||||
|
plugin));
|
||||||
|
|
||||||
ProjectAdded(uint64(managers.length-1));
|
|
||||||
|
ProjectAdded(idProject);
|
||||||
}
|
}
|
||||||
|
|
||||||
event ProjectAdded(uint64 indexed idProject);
|
event ProjectAdded(uint64 indexed idProject);
|
||||||
|
|
||||||
function updateProject(uint64 idProject, address newAddr, string newName, uint64 newCommitTime) {
|
function updateProject(
|
||||||
|
uint64 idProject,
|
||||||
|
address newAddr,
|
||||||
|
string newName,
|
||||||
|
uint64 newCommitTime)
|
||||||
|
{
|
||||||
NoteManager storage project = findManager(idProject);
|
NoteManager storage project = findManager(idProject);
|
||||||
require(project.managerType == NoteManagerType.Project);
|
require(project.managerType == NoteManagerType.Project);
|
||||||
require(project.addr == msg.sender);
|
require(project.addr == msg.sender);
|
||||||
@ -274,6 +298,17 @@ contract LiquidPledgingBase {
|
|||||||
return getNoteLevel(oldN) + 1;
|
return getNoteLevel(oldN) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// helper function that returns the max commit time of the owner and all the
|
||||||
|
// delegates
|
||||||
|
function maxCommitTime(Note n) internal returns(uint commitTime) {
|
||||||
|
NoteManager storage m = findManager(n.owner);
|
||||||
|
commitTime = m.commitTime;
|
||||||
|
|
||||||
|
for (uint i=0; i<n.delegationChain.length; i++) {
|
||||||
|
m = findManager(n.delegationChain[i]);
|
||||||
|
if (m.commitTime > commitTime) commitTime = m.commitTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// helper function that returns the project level solely to check that there
|
// helper function that returns the project level solely to check that there
|
||||||
// are not too many Projects that violate MAX_SUBPROJECT_LEVEL
|
// are not too many Projects that violate MAX_SUBPROJECT_LEVEL
|
||||||
@ -318,4 +353,11 @@ contract LiquidPledgingBase {
|
|||||||
return getOldestNoteNotCanceled(n.oldNote);
|
return getOldestNoteNotCanceled(n.oldNote);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function checkManagerOwner(NoteManager m) internal constant {
|
||||||
|
require((msg.sender == m.addr) || (msg.sender == address(m.plugin)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,8 @@ contract Owned {
|
|||||||
|
|
||||||
address public owner;
|
address public owner;
|
||||||
|
|
||||||
/// @notice The Constructor assigns the message sender to be `owner`
|
/// @notice The Constructor assigns the account deploying the contract to be
|
||||||
|
/// the `owner`
|
||||||
function Owned() {
|
function Owned() {
|
||||||
owner = msg.sender;
|
owner = msg.sender;
|
||||||
}
|
}
|
||||||
@ -22,13 +23,16 @@ contract Owned {
|
|||||||
address public newOwner;
|
address public newOwner;
|
||||||
|
|
||||||
/// @notice `owner` can step down and assign some other address to this role
|
/// @notice `owner` can step down and assign some other address to this role
|
||||||
/// @param _newOwner The address of the new owner. 0x0 can be used to create
|
/// but after this function is called the current owner still has ownership
|
||||||
/// an unowned neutral vault, however that cannot be undone
|
/// powers in this contract; change of ownership is a 2 step process
|
||||||
|
/// @param _newOwner The address of the new owner. A simple contract with
|
||||||
|
/// the abilitiy to accept ownership but the inability to do anything else
|
||||||
|
/// can be used to create an unowned contract to achieve decentralization
|
||||||
function changeOwner(address _newOwner) onlyOwner {
|
function changeOwner(address _newOwner) onlyOwner {
|
||||||
newOwner = _newOwner;
|
newOwner = _newOwner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @notice `newOwner` can accept ownership over this contract
|
||||||
function acceptOwnership() {
|
function acceptOwnership() {
|
||||||
if (msg.sender == newOwner) {
|
if (msg.sender == newOwner) {
|
||||||
owner = newOwner;
|
owner = newOwner;
|
||||||
|
18
package-lock.json
generated
18
package-lock.json
generated
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "liquidpledging",
|
"name": "liquidpledging",
|
||||||
"version": "0.0.1",
|
"version": "0.0.5",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -3595,14 +3595,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"string_decoder": {
|
|
||||||
"version": "1.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
|
|
||||||
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
|
|
||||||
"requires": {
|
|
||||||
"safe-buffer": "5.1.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"string-width": {
|
"string-width": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
||||||
@ -3623,6 +3615,14 @@
|
|||||||
"function-bind": "1.1.0"
|
"function-bind": "1.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"string_decoder": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
|
||||||
|
"requires": {
|
||||||
|
"safe-buffer": "5.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"stringstream": {
|
"stringstream": {
|
||||||
"version": "0.0.5",
|
"version": "0.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "liquidpledging",
|
"name": "liquidpledging",
|
||||||
"version": "0.0.3",
|
"version": "0.0.7",
|
||||||
"description": "Liquid Pledging Smart Contract",
|
"description": "Liquid Pledging Smart Contract",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
|
@ -26,15 +26,15 @@ const printBalances = async(liquidPledging) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const readTest = async(liquidPledging) => {
|
const readTest = async(liquidPledging) => {
|
||||||
t1 = await liquidPledging.test1();
|
const t1 = await liquidPledging.test1();
|
||||||
t2 = await liquidPledging.test2();
|
const t2 = await liquidPledging.test2();
|
||||||
t3 = await liquidPledging.test3();
|
const t3 = await liquidPledging.test3();
|
||||||
t4 = await liquidPledging.test4();
|
const t4 = await liquidPledging.test4();
|
||||||
console.log("t1: ", t1.toNumber());
|
console.log('t1: ', t1.toNumber());
|
||||||
console.log("t2: ", t2.toNumber());
|
console.log('t2: ', t2.toNumber());
|
||||||
console.log("t3: ", t3.toNumber());
|
console.log('t3: ', t3.toNumber());
|
||||||
console.log("t4: ", t4.toNumber());
|
console.log('t4: ', t4.toNumber());
|
||||||
}
|
};
|
||||||
|
|
||||||
describe('LiquidPledging test', () => {
|
describe('LiquidPledging test', () => {
|
||||||
let web3;
|
let web3;
|
||||||
@ -49,7 +49,7 @@ describe('LiquidPledging test', () => {
|
|||||||
let adminProject2a;
|
let adminProject2a;
|
||||||
let delegate2;
|
let delegate2;
|
||||||
before((done) => {
|
before((done) => {
|
||||||
ethConnector.init('testrpc', { gasLimit: 4700000 }, () => {
|
ethConnector.init('testrpc', { gasLimit: 5200000 }, () => {
|
||||||
web3 = ethConnector.web3;
|
web3 = ethConnector.web3;
|
||||||
accounts = ethConnector.accounts;
|
accounts = ethConnector.accounts;
|
||||||
donor1 = accounts[1];
|
donor1 = accounts[1];
|
||||||
@ -64,11 +64,11 @@ describe('LiquidPledging test', () => {
|
|||||||
});
|
});
|
||||||
it('Should deploy LiquidPledging contract', async () => {
|
it('Should deploy LiquidPledging contract', async () => {
|
||||||
vault = await Vault.new(web3);
|
vault = await Vault.new(web3);
|
||||||
liquidPledging = await LiquidPledging.new(web3, vault.$address);
|
liquidPledging = await LiquidPledging.new(web3, vault.$address, { gas: 5200000 });
|
||||||
await vault.setLiquidPledging(liquidPledging.$address);
|
await vault.setLiquidPledging(liquidPledging.$address);
|
||||||
}).timeout(6000);
|
}).timeout(6000);
|
||||||
it('Should create a donor', async () => {
|
it('Should create a donor', async () => {
|
||||||
await liquidPledging.addDonor('Donor1', 86400, { from: donor1 });
|
await liquidPledging.addDonor('Donor1', 86400, 0, { from: donor1 });
|
||||||
const nManagers = await liquidPledging.numberOfNoteManagers();
|
const nManagers = await liquidPledging.numberOfNoteManagers();
|
||||||
assert.equal(nManagers, 1);
|
assert.equal(nManagers, 1);
|
||||||
const res = await liquidPledging.getNoteManager(1);
|
const res = await liquidPledging.getNoteManager(1);
|
||||||
@ -84,7 +84,7 @@ describe('LiquidPledging test', () => {
|
|||||||
await liquidPledging.getNote(1);
|
await liquidPledging.getNote(1);
|
||||||
}).timeout(6000);
|
}).timeout(6000);
|
||||||
it('Should create a delegate', async () => {
|
it('Should create a delegate', async () => {
|
||||||
await liquidPledging.addDelegate('Delegate1', { from: delegate1 });
|
await liquidPledging.addDelegate('Delegate1', 0, 0, { from: delegate1 });
|
||||||
const nManagers = await liquidPledging.numberOfNoteManagers();
|
const nManagers = await liquidPledging.numberOfNoteManagers();
|
||||||
assert.equal(nManagers, 2);
|
assert.equal(nManagers, 2);
|
||||||
const res = await liquidPledging.getNoteManager(2);
|
const res = await liquidPledging.getNoteManager(2);
|
||||||
@ -108,7 +108,7 @@ describe('LiquidPledging test', () => {
|
|||||||
assert.equal(d[2], 'Delegate1');
|
assert.equal(d[2], 'Delegate1');
|
||||||
}).timeout(6000);
|
}).timeout(6000);
|
||||||
it('Should create a 2 projects', async () => {
|
it('Should create a 2 projects', async () => {
|
||||||
await liquidPledging.addProject('Project1', adminProject1, 0, 86400, { from: adminProject1 });
|
await liquidPledging.addProject('Project1', adminProject1, 0, 86400, 0, { from: adminProject1 });
|
||||||
|
|
||||||
const nManagers = await liquidPledging.numberOfNoteManagers();
|
const nManagers = await liquidPledging.numberOfNoteManagers();
|
||||||
assert.equal(nManagers, 3);
|
assert.equal(nManagers, 3);
|
||||||
@ -120,7 +120,7 @@ describe('LiquidPledging test', () => {
|
|||||||
assert.equal(res[4], 0);
|
assert.equal(res[4], 0);
|
||||||
assert.equal(res[5], false);
|
assert.equal(res[5], false);
|
||||||
|
|
||||||
await liquidPledging.addProject('Project2', adminProject2, 0, 86400, { from: adminProject2 });
|
await liquidPledging.addProject('Project2', adminProject2, 0, 86400, 0, { from: adminProject2 });
|
||||||
|
|
||||||
const nManagers2 = await liquidPledging.numberOfNoteManagers();
|
const nManagers2 = await liquidPledging.numberOfNoteManagers();
|
||||||
assert.equal(nManagers2, 4);
|
assert.equal(nManagers2, 4);
|
||||||
@ -236,8 +236,8 @@ describe('LiquidPledging test', () => {
|
|||||||
assert.equal(web3.fromWei(st.notes[4].amount).toNumber(), 0.12);
|
assert.equal(web3.fromWei(st.notes[4].amount).toNumber(), 0.12);
|
||||||
}).timeout(6000);
|
}).timeout(6000);
|
||||||
it('A subproject 2a and a delegate2 is created', async () => {
|
it('A subproject 2a and a delegate2 is created', async () => {
|
||||||
await liquidPledging.addProject('Project2a', adminProject2a, 4, 86400, { from: adminProject2 });
|
await liquidPledging.addProject('Project2a', adminProject2a, 4, 86400, 0, { from: adminProject2 });
|
||||||
await liquidPledging.addDelegate('Delegate2', { from: delegate2 });
|
await liquidPledging.addDelegate('Delegate2', 0, 0, { from: delegate2 });
|
||||||
const nManagers = await liquidPledging.numberOfNoteManagers();
|
const nManagers = await liquidPledging.numberOfNoteManagers();
|
||||||
assert.equal(nManagers, 6);
|
assert.equal(nManagers, 6);
|
||||||
}).timeout(6000);
|
}).timeout(6000);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user