mirror of
https://github.com/status-im/liquid-funding.git
synced 2025-02-21 23:58:06 +00:00
first pass at refactoring to Pledges lib
This commit is contained in:
parent
674397cc80
commit
4f2bf61dd2
@ -70,18 +70,19 @@ contract LiquidPledging is LiquidPledgingBase {
|
||||
require(amount > 0);
|
||||
vault.transfer(amount); // Sends the `msg.value` (in wei) to the `vault`
|
||||
|
||||
uint64 idPledge = findOrCreatePledge(
|
||||
uint64 idPledge = _storage.findOrCreatePledge(
|
||||
idGiver,
|
||||
new uint64[](0), // Creates empty array for delegationChain
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
PledgeState.Pledged
|
||||
Pledges.PledgeState.Pledged
|
||||
);
|
||||
|
||||
|
||||
Pledge storage nTo = findPledge(idPledge);
|
||||
nTo.amount += amount;
|
||||
uint pAmount = _storage.getPledgeAmount(idPledge);
|
||||
pAmount += amount;
|
||||
_storage.setPledgeAmount(idPledge, pAmount);
|
||||
|
||||
Transfer(0, idPledge, amount); // An event
|
||||
|
||||
@ -107,10 +108,10 @@ contract LiquidPledging is LiquidPledgingBase {
|
||||
|
||||
idPledge = normalizePledge(idPledge);
|
||||
|
||||
Pledge storage p = findPledge(idPledge);
|
||||
Pledges.Pledge memory p = _storage.findPledge(idPledge);
|
||||
PledgeAdmins.PledgeAdminType receiverAdminType = _storage.getAdminType(idReceiver);
|
||||
|
||||
require(p.pledgeState == PledgeState.Pledged);
|
||||
require(p.pledgeState == Pledges.PledgeState.Pledged);
|
||||
|
||||
// If the sender is the owner of the Pledge
|
||||
if (p.owner == idSender) {
|
||||
@ -128,13 +129,13 @@ contract LiquidPledging is LiquidPledgingBase {
|
||||
// intendedProject by the owner
|
||||
|
||||
if (recieverDIdx == p.delegationChain.length - 1) {
|
||||
uint64 toPledge = findOrCreatePledge(
|
||||
uint64 toPledge = _storage.findOrCreatePledge(
|
||||
p.owner,
|
||||
p.delegationChain,
|
||||
0,
|
||||
0,
|
||||
p.oldPledge,
|
||||
PledgeState.Pledged);
|
||||
Pledges.PledgeState.Pledged);
|
||||
doTransfer(idPledge, toPledge, amount);
|
||||
} else {
|
||||
undelegate(idPledge, amount, p.delegationChain.length - receiverDIdx - 1);
|
||||
@ -229,17 +230,17 @@ contract LiquidPledging is LiquidPledgingBase {
|
||||
/// @param amount Quantity of ether (in wei) to be authorized
|
||||
function withdraw(uint64 idPledge, uint amount) public {
|
||||
idPledge = normalizePledge(idPledge); // Updates pledge info
|
||||
Pledge storage p = findPledge(idPledge);
|
||||
require(p.pledgeState == PledgeState.Pledged);
|
||||
Pledges.Pledge memory p = _storage.findPledge(idPledge);
|
||||
require(p.pledgeState == Pledges.PledgeState.Pledged);
|
||||
checkAdminOwner(p.owner);
|
||||
|
||||
uint64 idNewPledge = findOrCreatePledge(
|
||||
uint64 idNewPledge = _storage.findOrCreatePledge(
|
||||
p.owner,
|
||||
p.delegationChain,
|
||||
0,
|
||||
0,
|
||||
p.oldPledge,
|
||||
PledgeState.Paying
|
||||
Pledges.PledgeState.Paying
|
||||
);
|
||||
|
||||
doTransfer(idPledge, idNewPledge, amount);
|
||||
@ -247,44 +248,44 @@ contract LiquidPledging is LiquidPledgingBase {
|
||||
vault.authorizePayment(bytes32(idNewPledge), _storage.getAdminAddr(p.owner), amount);
|
||||
}
|
||||
|
||||
/// @notice `onlyVault` Confirms a withdraw request changing the PledgeState
|
||||
/// @notice `onlyVault` Confirms a withdraw request changing the Pledges.PledgeState
|
||||
/// from Paying to Paid
|
||||
/// @param idPledge Id of the pledge that is to be withdrawn
|
||||
/// @param amount Quantity of ether (in wei) to be withdrawn
|
||||
function confirmPayment(uint64 idPledge, uint amount) public onlyVault {
|
||||
Pledge storage p = findPledge(idPledge);
|
||||
Pledges.Pledge memory p = _storage.findPledge(idPledge);
|
||||
|
||||
require(p.pledgeState == PledgeState.Paying);
|
||||
require(p.pledgeState == Pledges.PledgeState.Paying);
|
||||
|
||||
uint64 idNewPledge = findOrCreatePledge(
|
||||
uint64 idNewPledge = _storage.findOrCreatePledge(
|
||||
p.owner,
|
||||
p.delegationChain,
|
||||
0,
|
||||
0,
|
||||
p.oldPledge,
|
||||
PledgeState.Paid
|
||||
Pledges.PledgeState.Paid
|
||||
);
|
||||
|
||||
doTransfer(idPledge, idNewPledge, amount);
|
||||
}
|
||||
|
||||
/// @notice `onlyVault` Cancels a withdraw request, changing the PledgeState
|
||||
/// @notice `onlyVault` Cancels a withdraw request, changing the Pledges.PledgeState
|
||||
/// from Paying back to Pledged
|
||||
/// @param idPledge Id of the pledge that's withdraw is to be canceled
|
||||
/// @param amount Quantity of ether (in wei) to be canceled
|
||||
function cancelPayment(uint64 idPledge, uint amount) public onlyVault {
|
||||
Pledge storage p = findPledge(idPledge);
|
||||
Pledges.Pledge memory p = _storage.findPledge(idPledge);
|
||||
|
||||
require(p.pledgeState == PledgeState.Paying); //TODO change to revert????????????????????????????
|
||||
require(p.pledgeState == Pledges.PledgeState.Paying); //TODO change to revert????????????????????????????
|
||||
|
||||
// When a payment is canceled, never is assigned to a project.
|
||||
uint64 oldPledge = findOrCreatePledge(
|
||||
uint64 oldPledge = _storage.findOrCreatePledge(
|
||||
p.owner,
|
||||
p.delegationChain,
|
||||
0,
|
||||
0,
|
||||
p.oldPledge,
|
||||
PledgeState.Pledged
|
||||
Pledges.PledgeState.Pledged
|
||||
);
|
||||
|
||||
oldPledge = normalizePledge(oldPledge);
|
||||
@ -307,7 +308,7 @@ contract LiquidPledging is LiquidPledgingBase {
|
||||
function cancelPledge(uint64 idPledge, uint amount) public {
|
||||
idPledge = normalizePledge(idPledge);
|
||||
|
||||
Pledge storage p = findPledge(idPledge);
|
||||
Pledges.Pledge memory p = _storage.findPledge(idPledge);
|
||||
require(p.oldPledge != 0);
|
||||
|
||||
checkAdminOwner(p.owner);
|
||||
@ -415,28 +416,28 @@ contract LiquidPledging is LiquidPledgingBase {
|
||||
uint amount,
|
||||
uint64 idReceiver
|
||||
) internal {
|
||||
Pledge storage p = findPledge(idPledge);
|
||||
Pledges.Pledge memory p = _storage.findPledge(idPledge);
|
||||
|
||||
// Ensure that the pledge is not already at max pledge depth
|
||||
// and the project has not been canceled
|
||||
require(getPledgeLevel(p) < MAX_INTERPROJECT_LEVEL);
|
||||
require(_storage.getPledgeLevel(p.oldPledge) < MAX_INTERPROJECT_LEVEL);
|
||||
require(!_storage.isProjectCanceled(idReceiver));
|
||||
|
||||
uint64 oldPledge = findOrCreatePledge(
|
||||
uint64 oldPledge = _storage.findOrCreatePledge(
|
||||
p.owner,
|
||||
p.delegationChain,
|
||||
0,
|
||||
0,
|
||||
p.oldPledge,
|
||||
PledgeState.Pledged
|
||||
Pledges.PledgeState.Pledged
|
||||
);
|
||||
uint64 toPledge = findOrCreatePledge(
|
||||
uint64 toPledge = _storage.findOrCreatePledge(
|
||||
idReceiver, // Set the new owner
|
||||
new uint64[](0), // clear the delegation chain
|
||||
0,
|
||||
0,
|
||||
oldPledge,
|
||||
PledgeState.Pledged
|
||||
Pledges.PledgeState.Pledged
|
||||
);
|
||||
doTransfer(idPledge, toPledge, amount);
|
||||
}
|
||||
@ -453,13 +454,13 @@ contract LiquidPledging is LiquidPledgingBase {
|
||||
uint amount,
|
||||
uint64 idReceiver
|
||||
) internal {
|
||||
uint64 toPledge = findOrCreatePledge(
|
||||
uint64 toPledge = _storage.findOrCreatePledge(
|
||||
idReceiver,
|
||||
new uint64[](0),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
PledgeState.Pledged
|
||||
Pledges.PledgeState.Pledged
|
||||
);
|
||||
doTransfer(idPledge, toPledge, amount);
|
||||
}
|
||||
@ -474,7 +475,7 @@ contract LiquidPledging is LiquidPledgingBase {
|
||||
uint amount,
|
||||
uint64 idReceiver
|
||||
) internal {
|
||||
Pledge storage p = findPledge(idPledge);
|
||||
Pledges.Pledge memory p = _storage.findPledge(idPledge);
|
||||
|
||||
require(p.delegationChain.length < MAX_DELEGATES);
|
||||
uint64[] memory newDelegationChain = new uint64[](
|
||||
@ -487,13 +488,13 @@ contract LiquidPledging is LiquidPledgingBase {
|
||||
// Make the last item in the array the idReceiver
|
||||
newDelegationChain[p.delegationChain.length] = idReceiver;
|
||||
|
||||
uint64 toPledge = findOrCreatePledge(
|
||||
uint64 toPledge = _storage.findOrCreatePledge(
|
||||
p.owner,
|
||||
newDelegationChain,
|
||||
0,
|
||||
0,
|
||||
p.oldPledge,
|
||||
PledgeState.Pledged
|
||||
Pledges.PledgeState.Pledged
|
||||
);
|
||||
doTransfer(idPledge, toPledge, amount);
|
||||
}
|
||||
@ -510,7 +511,7 @@ contract LiquidPledging is LiquidPledgingBase {
|
||||
uint q
|
||||
) internal returns (uint64)
|
||||
{
|
||||
Pledge storage p = findPledge(idPledge);
|
||||
Pledges.Pledge memory p = _storage.findPledge(idPledge);
|
||||
uint64[] memory newDelegationChain = new uint64[](
|
||||
p.delegationChain.length - q
|
||||
);
|
||||
@ -518,13 +519,13 @@ contract LiquidPledging is LiquidPledgingBase {
|
||||
for (uint i=0; i<p.delegationChain.length - q; i++) {
|
||||
newDelegationChain[i] = p.delegationChain[i];
|
||||
}
|
||||
uint64 toPledge = findOrCreatePledge(
|
||||
uint64 toPledge = _storage.findOrCreatePledge(
|
||||
p.owner,
|
||||
newDelegationChain,
|
||||
0,
|
||||
0,
|
||||
p.oldPledge,
|
||||
PledgeState.Pledged
|
||||
Pledges.PledgeState.Pledged
|
||||
);
|
||||
doTransfer(idPledge, toPledge, amount);
|
||||
|
||||
@ -543,18 +544,18 @@ contract LiquidPledging is LiquidPledgingBase {
|
||||
uint amount,
|
||||
uint64 idReceiver
|
||||
) internal {
|
||||
Pledge storage p = findPledge(idPledge);
|
||||
Pledges.Pledge memory p = _storage.findPledge(idPledge);
|
||||
|
||||
require(getPledgeLevel(p) < MAX_INTERPROJECT_LEVEL);
|
||||
require(_storage.getPledgeLevel(p.oldPledge) < MAX_INTERPROJECT_LEVEL);
|
||||
require(!_storage.isProjectCanceled(idReceiver));
|
||||
|
||||
uint64 toPledge = findOrCreatePledge(
|
||||
uint64 toPledge = _storage.findOrCreatePledge(
|
||||
p.owner,
|
||||
p.delegationChain,
|
||||
idReceiver,
|
||||
uint64(getTime() + maxCommitTime(p)),
|
||||
p.oldPledge,
|
||||
PledgeState.Pledged
|
||||
Pledges.PledgeState.Pledged
|
||||
);
|
||||
doTransfer(idPledge, toPledge, amount);
|
||||
}
|
||||
@ -573,8 +574,8 @@ contract LiquidPledging is LiquidPledgingBase {
|
||||
if (amount == 0) {
|
||||
return;
|
||||
}
|
||||
Pledge storage nFrom = findPledge(from);
|
||||
Pledge storage nTo = findPledge(to);
|
||||
Pledges.Pledge memory nFrom = _storage.findPledge(from);
|
||||
Pledges.Pledge memory nTo = _storage.findPledge(to);
|
||||
require(nFrom.amount >= amount);
|
||||
nFrom.amount -= amount;
|
||||
nTo.amount += amount;
|
||||
@ -583,7 +584,7 @@ contract LiquidPledging is LiquidPledgingBase {
|
||||
// callPlugins(false, from, to, amount);
|
||||
}
|
||||
|
||||
/// @notice Only affects pledges with the Pledged PledgeState for 2 things:
|
||||
/// @notice Only affects pledges with the Pledged Pledges.PledgeState for 2 things:
|
||||
/// #1: Checks if the pledge should be committed. This means that
|
||||
/// if the pledge has an intendedProject and it is past the
|
||||
/// commitTime, it changes the owner to be the proposed project
|
||||
@ -602,35 +603,35 @@ contract LiquidPledging is LiquidPledgingBase {
|
||||
/// @return The normalized Pledge!
|
||||
function normalizePledge(uint64 idPledge) public returns(uint64) {
|
||||
|
||||
Pledge storage p = findPledge(idPledge);
|
||||
Pledges.Pledge memory p = _storage.findPledge(idPledge);
|
||||
|
||||
// Check to make sure this pledge hasn't already been used
|
||||
// or is in the process of being used
|
||||
if (p.pledgeState != PledgeState.Pledged) {
|
||||
if (p.pledgeState != Pledges.PledgeState.Pledged) {
|
||||
return idPledge;
|
||||
}
|
||||
|
||||
// First send to a project if it's proposed and committed
|
||||
if ((p.intendedProject > 0) && ( getTime() > p.commitTime)) {
|
||||
uint64 oldPledge = findOrCreatePledge(
|
||||
uint64 oldPledge = _storage.findOrCreatePledge(
|
||||
p.owner,
|
||||
p.delegationChain,
|
||||
0,
|
||||
0,
|
||||
p.oldPledge,
|
||||
PledgeState.Pledged
|
||||
Pledges.PledgeState.Pledged
|
||||
);
|
||||
uint64 toPledge = findOrCreatePledge(
|
||||
uint64 toPledge = _storage.findOrCreatePledge(
|
||||
p.intendedProject,
|
||||
new uint64[](0),
|
||||
0,
|
||||
0,
|
||||
oldPledge,
|
||||
PledgeState.Pledged
|
||||
Pledges.PledgeState.Pledged
|
||||
);
|
||||
doTransfer(idPledge, toPledge, p.amount);
|
||||
idPledge = toPledge;
|
||||
p = findPledge(idPledge);
|
||||
p = _storage.findPledge(idPledge);
|
||||
}
|
||||
|
||||
toPledge = getOldestPledgeNotCanceled(idPledge);
|
||||
@ -720,7 +721,7 @@ contract LiquidPledging is LiquidPledgingBase {
|
||||
// or transferring context
|
||||
uint64 offset = idPledge == fromPledge ? 0 : 256;
|
||||
allowedAmount = amount;
|
||||
Pledge storage p = findPledge(idPledge);
|
||||
Pledges.Pledge memory p = _storage.findPledge(idPledge);
|
||||
|
||||
// TODO I think we can remove these check b/c the admins array only grows, thus if adminId is out of index, it will just return 0x0 & skip the plugin call
|
||||
// uint adminsSize = _storage.pledgeAdminsCount();
|
||||
|
@ -21,6 +21,7 @@ pragma solidity ^0.4.11;
|
||||
import "./ILiquidPledgingPlugin.sol";
|
||||
import "giveth-common-contracts/contracts/Escapable.sol";
|
||||
import "./PledgeAdmins.sol";
|
||||
import "./Pledges.sol";
|
||||
import "./EternalStorage.sol";
|
||||
|
||||
/// @dev This is an interface for `LPVault` which serves as a secure storage for
|
||||
@ -36,32 +37,14 @@ interface LPVault {
|
||||
/// data structures
|
||||
contract LiquidPledgingBase is Escapable {
|
||||
using PledgeAdmins for EternalStorage;
|
||||
using Pledges for EternalStorage;
|
||||
|
||||
// Limits inserted to prevent large loops that could prevent canceling
|
||||
uint constant MAX_DELEGATES = 10;
|
||||
uint constant MAX_SUBPROJECT_LEVEL = 20;
|
||||
uint constant MAX_INTERPROJECT_LEVEL = 20;
|
||||
|
||||
enum PledgeState { Pledged, Paying, Paid }
|
||||
|
||||
struct Pledge {
|
||||
uint amount;
|
||||
uint64 owner; // PledgeAdmin
|
||||
uint64[] delegationChain; // List of delegates in order of authority
|
||||
uint64 intendedProject; // Used when delegates are sending to projects
|
||||
uint64 commitTime; // When the intendedProject will become the owner
|
||||
uint64 oldPledge; // Points to the id that this Pledge was derived from
|
||||
PledgeState pledgeState; // Pledged, Paying, Paid
|
||||
}
|
||||
|
||||
EternalStorage public _storage;
|
||||
Pledge[] pledges;
|
||||
|
||||
/// @dev this mapping allows you to search for a specific pledge's
|
||||
/// index number by the hash of that pledge
|
||||
mapping (bytes32 => uint64) hPledge2idx;
|
||||
|
||||
|
||||
LPVault public vault;
|
||||
|
||||
mapping (bytes32 => bool) pluginWhitelist;
|
||||
@ -76,9 +59,6 @@ contract LiquidPledgingBase is Escapable {
|
||||
event ProjectAdded(uint indexed idProject);
|
||||
event ProjectUpdated(uint indexed idProject);
|
||||
|
||||
// for testing
|
||||
event Gas(uint remainingGas);
|
||||
|
||||
/////////////
|
||||
// Modifiers
|
||||
/////////////
|
||||
@ -91,6 +71,12 @@ contract LiquidPledgingBase is Escapable {
|
||||
_;
|
||||
}
|
||||
|
||||
/// @notice A check to see if the msg.sender is the owner or the
|
||||
/// plugin contract for a specific Admin
|
||||
/// @param idAdmin The id of the admin being checked
|
||||
function checkAdminOwner(uint idAdmin) internal constant {
|
||||
require(msg.sender == _storage.getAdminPlugin(idAdmin) || msg.sender == _storage.getAdminAddr(idAdmin));
|
||||
}
|
||||
|
||||
///////////////
|
||||
// Constructor
|
||||
@ -230,8 +216,8 @@ contract LiquidPledgingBase is Escapable {
|
||||
|
||||
/// @notice A constant getter that returns the total number of pledges
|
||||
/// @return The total number of Pledges in the system
|
||||
function numberOfPledges() public constant returns (uint) {
|
||||
return pledges.length - 1;
|
||||
function numberOfPledges() public view returns (uint) {
|
||||
return _storage.pledgesCount();
|
||||
}
|
||||
|
||||
/// @notice A getter that returns the details of the specified pledge
|
||||
@ -246,12 +232,12 @@ contract LiquidPledgingBase is Escapable {
|
||||
uint64 intendedProject,
|
||||
uint64 commitTime,
|
||||
uint64 oldPledge,
|
||||
PledgeState pledgeState
|
||||
Pledges.PledgeState pledgeState
|
||||
) {
|
||||
Pledge storage p = findPledge(idPledge);
|
||||
Pledges.Pledge memory p = _storage.findPledge(idPledge);
|
||||
amount = p.amount;
|
||||
owner = p.owner;
|
||||
nDelegates = uint64(p.delegationChain.length);
|
||||
nDelegates = uint64(_storage.getPledgeDelegateCount(idPledge));
|
||||
intendedProject = p.intendedProject;
|
||||
commitTime = p.commitTime;
|
||||
oldPledge = p.oldPledge;
|
||||
@ -266,81 +252,37 @@ contract LiquidPledgingBase is Escapable {
|
||||
address addr,
|
||||
string name
|
||||
) {
|
||||
Pledge storage p = findPledge(idPledge);
|
||||
idDelegate = p.delegationChain[idxDelegate - 1];
|
||||
require(_storage.pledgeAdminsCount() >= idxDelegate);
|
||||
idDelegate = uint64(_storage.getPledgeDelegate(idPledge, idxDelegate));
|
||||
addr = _storage.getAdminAddr(idDelegate);
|
||||
name = _storage.getAdminName(idDelegate);
|
||||
}
|
||||
|
||||
/// @notice A constant getter used to check how many total Admins exist
|
||||
/// @return The total number of admins (Givers, Delegates and Projects) .
|
||||
// function numberOfPledgeAdmins() public constant returns(uint) {
|
||||
// return _storage.pledgeAdminsCount();
|
||||
// }
|
||||
function numberOfPledgeAdmins() public constant returns(uint) {
|
||||
return _storage.pledgeAdminsCount();
|
||||
}
|
||||
|
||||
// can use _storage.getAdmin(idAdmin);
|
||||
// function getPledgeAdmin(uint64 idAdmin) public constant returns (
|
||||
// PledgeAdmins.PledgeAdminType adminType,
|
||||
// address addr,
|
||||
// string name,
|
||||
// string url,
|
||||
// uint64 commitTime,
|
||||
// uint64 parentProject,
|
||||
// bool canceled,
|
||||
// address plugin)
|
||||
// {
|
||||
// (adminType, addr, name, url, commitTime, parentProject, canceled, plugin) = _storage.getAdmin(idAdmin);
|
||||
// }
|
||||
function getPledgeAdmin(uint64 idAdmin) public constant returns (
|
||||
PledgeAdmins.PledgeAdminType adminType,
|
||||
address addr,
|
||||
string name,
|
||||
string url,
|
||||
uint64 commitTime,
|
||||
uint64 parentProject,
|
||||
bool canceled,
|
||||
address plugin)
|
||||
{
|
||||
// uint p;
|
||||
// (adminType, addr, name, url, commitTime, p, canceled, plugin) = _storage.getAdmin(idAdmin);
|
||||
return _storage.getAdmin(idAdmin);
|
||||
// parentProject = uint64(p);
|
||||
}
|
||||
|
||||
////////
|
||||
// Private methods
|
||||
///////
|
||||
|
||||
/// @notice This creates a Pledge with an initial amount of 0 if one is not
|
||||
/// created already; otherwise it finds the pledge with the specified
|
||||
/// attributes; all pledges technically exist, if the pledge hasn't been
|
||||
/// created in this system yet it simply isn't in the hash array
|
||||
/// hPledge2idx[] yet
|
||||
/// @param owner The owner of the pledge being looked up
|
||||
/// @param delegationChain The list of delegates in order of authority
|
||||
/// @param intendedProject The project this pledge will Fund after the
|
||||
/// commitTime has passed
|
||||
/// @param commitTime The length of time in seconds the Giver has to
|
||||
/// veto when the Giver's delegates Pledge funds to a project
|
||||
/// @param oldPledge This value is used to store the pledge the current
|
||||
/// pledge was came from, and in the case a Project is canceled, the Pledge
|
||||
/// will revert back to it's previous state
|
||||
/// @param state The pledge state: Pledged, Paying, or state
|
||||
/// @return The hPledge2idx index number
|
||||
function findOrCreatePledge(
|
||||
uint64 owner,
|
||||
uint64[] delegationChain,
|
||||
uint64 intendedProject,
|
||||
uint64 commitTime,
|
||||
uint64 oldPledge,
|
||||
PledgeState state
|
||||
) internal returns (uint64)
|
||||
{
|
||||
bytes32 hPledge = keccak256(
|
||||
owner, delegationChain, intendedProject, commitTime, oldPledge, state);
|
||||
uint64 idx = hPledge2idx[hPledge];
|
||||
if (idx > 0) return idx;
|
||||
idx = uint64(pledges.length);
|
||||
hPledge2idx[hPledge] = idx;
|
||||
pledges.push(Pledge(
|
||||
0, owner, delegationChain, intendedProject, commitTime, oldPledge, state));
|
||||
return idx;
|
||||
}
|
||||
|
||||
/// @notice A getter to look up a Pledge's details
|
||||
/// @param idPledge The id for the Pledge to lookup
|
||||
/// @return The PledgeA struct for the specified Pledge
|
||||
function findPledge(uint64 idPledge) internal view returns (Pledge storage) {
|
||||
require(idPledge < pledges.length);
|
||||
return pledges[idPledge];
|
||||
}
|
||||
|
||||
// a constant for when a delegate is requested that is not in the system
|
||||
uint64 constant NOTFOUND = 0xFFFFFFFFFFFFFFFF;
|
||||
|
||||
@ -352,28 +294,18 @@ contract LiquidPledgingBase is Escapable {
|
||||
/// `admins` array index `idDelegate` this returns that delegates
|
||||
/// corresponding index in the delegationChain. Otherwise it returns
|
||||
/// the NOTFOUND constant
|
||||
function getDelegateIdx(Pledge p, uint64 idDelegate) internal pure returns(uint64) {
|
||||
function getDelegateIdx(Pledges.Pledge p, uint64 idDelegate) internal pure returns(uint64) {
|
||||
for (uint i=0; i < p.delegationChain.length; i++) {
|
||||
if (p.delegationChain[i] == idDelegate) return uint64(i);
|
||||
}
|
||||
return NOTFOUND;
|
||||
}
|
||||
|
||||
/// @notice A getter to find how many old "parent" pledges a specific Pledge
|
||||
/// had using a self-referential loop
|
||||
/// @param p The Pledge being queried
|
||||
/// @return The number of old "parent" pledges a specific Pledge had
|
||||
function getPledgeLevel(Pledge p) internal returns(uint) {
|
||||
if (p.oldPledge == 0) return 0;
|
||||
Pledge storage oldN = findPledge(p.oldPledge);
|
||||
return getPledgeLevel(oldN) + 1; // a loop lookup
|
||||
}
|
||||
|
||||
/// @notice A getter to find the longest commitTime out of the owner and all
|
||||
/// the delegates for a specified pledge
|
||||
/// @param p The Pledge being queried
|
||||
/// @return The maximum commitTime out of the owner and all the delegates
|
||||
function maxCommitTime(Pledge p) internal view returns(uint commitTime) {
|
||||
function maxCommitTime(Pledges.Pledge p) internal view returns(uint commitTime) {
|
||||
uint adminsSize = _storage.pledgeAdminsCount();
|
||||
require(adminsSize >= p.owner);
|
||||
|
||||
@ -393,25 +325,19 @@ contract LiquidPledgingBase is Escapable {
|
||||
/// @return The oldest idPledge that hasn't been canceled (DUH!)
|
||||
function getOldestPledgeNotCanceled(
|
||||
uint64 idPledge
|
||||
) internal constant returns(uint64)
|
||||
) internal view returns(uint64)
|
||||
{
|
||||
if (idPledge == 0) return 0;
|
||||
Pledge storage p = findPledge(idPledge);
|
||||
uint owner = _storage.getPledgeOwner(idPledge);
|
||||
|
||||
PledgeAdmins.PledgeAdminType adminType = _storage.getAdminType(p.owner);
|
||||
PledgeAdmins.PledgeAdminType adminType = _storage.getAdminType(owner);
|
||||
if (adminType == PledgeAdmins.PledgeAdminType.Giver) return idPledge;
|
||||
assert(adminType == PledgeAdmins.PledgeAdminType.Project);
|
||||
|
||||
if (!_storage.isProjectCanceled(p.owner)) return idPledge;
|
||||
if (!_storage.isProjectCanceled(owner)) return idPledge;
|
||||
|
||||
return getOldestPledgeNotCanceled(p.oldPledge);
|
||||
}
|
||||
|
||||
/// @notice A check to see if the msg.sender is the owner or the
|
||||
/// plugin contract for a specific Admin
|
||||
/// @param idAdmin The id of the admin being checked
|
||||
function checkAdminOwner(uint idAdmin) internal constant {
|
||||
require((msg.sender == _storage.getAdminPlugin(idAdmin)) || (msg.sender == _storage.getAdminAddr(idAdmin)));
|
||||
uint64 oldPledge = uint64(_storage.getPledgeOldPledge(idPledge));
|
||||
return getOldestPledgeNotCanceled(oldPledge);
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
|
@ -34,7 +34,7 @@ contract LiquidPledgingMock is LiquidPledging {
|
||||
address _vault,
|
||||
address _escapeHatchCaller,
|
||||
address _escapeHatchDestination
|
||||
) LiquidPledging(_storage, _vault, _escapeHatchCaller, _escapeHatchDestination) {
|
||||
) LiquidPledging(_storage, _vault, _escapeHatchCaller, _escapeHatchDestination) public {
|
||||
mock_time = now;
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ contract LiquidPledgingMock is LiquidPledging {
|
||||
/// the mock_time parameter
|
||||
/// @param _t This is the value to which the mocked time
|
||||
/// will be set.
|
||||
function setMockedTime(uint _t) {
|
||||
function setMockedTime(uint _t) public {
|
||||
mock_time = _t;
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,9 @@ pragma solidity ^0.4.18;
|
||||
import "./ILiquidPledgingPlugin.sol";
|
||||
import "./EternallyPersistentLib.sol";
|
||||
|
||||
//18,446,744,070,000,000,000 uint64
|
||||
//1,516,144,546,228,000 uint56
|
||||
|
||||
library PledgeAdmins {
|
||||
using EternallyPersistentLib for EternalStorage;
|
||||
|
||||
@ -30,7 +33,7 @@ library PledgeAdmins {
|
||||
uint commitTime,
|
||||
ILiquidPledgingPlugin plugin
|
||||
) internal returns (uint idGiver) {
|
||||
idGiver = _storage.stgCollectionAddItem(admins);//, idGiver);
|
||||
idGiver = _storage.stgCollectionAddItem(admins);
|
||||
|
||||
// Save the fields
|
||||
_storage.stgObjectSetUInt(class, idGiver, "adminType", uint(PledgeAdminType.Giver));
|
||||
@ -248,7 +251,7 @@ library PledgeAdmins {
|
||||
/// @notice A constant getter used to check how many total Admins exist
|
||||
/// @return The total number of admins (Givers, Delegates and Projects) .
|
||||
function pledgeAdminsCount(EternalStorage _storage) internal constant returns(uint) {
|
||||
return _storage.stgCollectionLength(admins);// - 1;
|
||||
return _storage.stgCollectionLength(admins);
|
||||
}
|
||||
|
||||
/// @notice A constant getter to check the details of a specified Admin
|
||||
@ -270,7 +273,7 @@ library PledgeAdmins {
|
||||
string name,
|
||||
string url,
|
||||
uint64 commitTime,
|
||||
uint parentProject,
|
||||
uint64 parentProject,
|
||||
bool canceled,
|
||||
address plugin
|
||||
)
|
||||
@ -284,7 +287,7 @@ library PledgeAdmins {
|
||||
// parentProject & canceled only belong to Project admins,
|
||||
// so don't waste the gas to fetch the data
|
||||
if (adminType == PledgeAdminType.Project) {
|
||||
parentProject = getAdminParentProject(_storage, idAdmin);
|
||||
parentProject = uint64(getAdminParentProject(_storage, idAdmin));
|
||||
canceled = getAdminCanceled(_storage, idAdmin);
|
||||
}
|
||||
|
||||
@ -302,9 +305,6 @@ library PledgeAdmins {
|
||||
return getProjectLevel(_storage, parentProject) + 1;
|
||||
}
|
||||
|
||||
//18,446,744,070,000,000,000 uint64
|
||||
//1,516,144,546,228,000 uint56
|
||||
|
||||
////////
|
||||
// Methods to fetch individual attributes of a PledgeAdmin
|
||||
///////
|
||||
|
184
contracts/Pledges.sol
Normal file
184
contracts/Pledges.sol
Normal file
@ -0,0 +1,184 @@
|
||||
pragma solidity ^0.4.18;
|
||||
|
||||
import "./EternallyPersistentLib.sol";
|
||||
|
||||
library Pledges {
|
||||
using EternallyPersistentLib for EternalStorage;
|
||||
|
||||
string constant class = "Pledge";
|
||||
bytes32 constant pledges = keccak256("pledges");
|
||||
|
||||
enum PledgeState { Pledged, Paying, Paid }
|
||||
|
||||
struct Pledge {
|
||||
uint id;
|
||||
uint amount;
|
||||
uint64 owner; // PledgeAdmin
|
||||
uint64[] delegationChain; // List of delegates in order of authority
|
||||
uint64 intendedProject; // Used when delegates are sending to projects
|
||||
uint64 commitTime; // When the intendedProject will become the owner
|
||||
uint64 oldPledge; // Points to the id that this Pledge was derived from
|
||||
PledgeState pledgeState; // Pledged, Paying, Paid
|
||||
}
|
||||
|
||||
function pledgesCount(EternalStorage _storage) internal view returns(uint) {
|
||||
return _storage.stgCollectionLength(pledges);
|
||||
}
|
||||
|
||||
/// @notice This creates a Pledge with an initial amount of 0 if one is not
|
||||
/// created already; otherwise it finds the pledge with the specified
|
||||
/// attributes; all pledges technically exist, if the pledge hasn't been
|
||||
/// created in this system yet it simply isn't in the hash array
|
||||
/// hPledge2idx[] yet
|
||||
/// @param owner The owner of the pledge being looked up
|
||||
/// @param delegationChain The list of delegates in order of authority
|
||||
/// @param intendedProject The project this pledge will Fund after the
|
||||
/// commitTime has passed
|
||||
/// @param commitTime The length of time in seconds the Giver has to
|
||||
/// veto when the Giver's delegates Pledge funds to a project
|
||||
/// @param oldPledge This value is used to store the pledge the current
|
||||
/// pledge was came from, and in the case a Project is canceled, the Pledge
|
||||
/// will revert back to it's previous state
|
||||
/// @param state The pledge state: Pledged, Paying, or state
|
||||
/// @return The hPledge2idx index number
|
||||
function findOrCreatePledge(
|
||||
EternalStorage _storage,
|
||||
uint64 owner,
|
||||
uint64[] delegationChain,
|
||||
uint64 intendedProject,
|
||||
uint64 commitTime,
|
||||
uint64 oldPledge,
|
||||
PledgeState state
|
||||
) internal returns (uint64)
|
||||
{
|
||||
bytes32 hPledge = keccak256(owner, delegationChain, intendedProject, commitTime, oldPledge, state);
|
||||
uint id = _storage.getUIntValue(hPledge);
|
||||
if (id > 0) return uint64(id);
|
||||
|
||||
id = _storage.stgCollectionAddItem(pledges);
|
||||
_storage.setUIntValue(hPledge, id);
|
||||
|
||||
_storage.stgObjectSetUInt(class, id, "owner", owner);
|
||||
if (intendedProject > 0) {
|
||||
_storage.stgObjectSetUInt(class, id, "intendedProject", intendedProject);
|
||||
}
|
||||
if (commitTime > 0) {
|
||||
_storage.stgObjectSetUInt(class, id, "commitTime", commitTime);
|
||||
}
|
||||
if (oldPledge > 0) {
|
||||
_storage.stgObjectSetUInt(class, id, "oldPledge", oldPledge);
|
||||
}
|
||||
_storage.stgObjectSetUInt(class, id, "state", uint(state));
|
||||
|
||||
if (delegationChain.length > 0) {
|
||||
_storage.setUIntValue(keccak256("delegationChain", id, "length"), delegationChain.length);
|
||||
|
||||
// TODO pack these? possibly add array method to EternalStorage in anticipation of the new solidity abi encoder
|
||||
for (uint i=0; i < delegationChain.length; i++) {
|
||||
_storage.setUIntValue(keccak256("delegationChain", id, i), delegationChain[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return uint64(id);
|
||||
}
|
||||
|
||||
function findPledge(EternalStorage _storage, uint idPledge) internal view returns(Pledge) {
|
||||
require(idPledge <= pledgesCount(_storage));
|
||||
|
||||
uint amount = getPledgeAmount(_storage, idPledge);
|
||||
uint owner = getPledgeOwner(_storage, idPledge);
|
||||
uint intendedProject = getPledgeIntendedProject(_storage, idPledge);
|
||||
uint commitTime = getPledgeCommitTime(_storage, idPledge);
|
||||
uint oldPledge = getPledgeOldPledge(_storage, idPledge);
|
||||
PledgeState state = getPledgeState(_storage, idPledge);
|
||||
uint64[] memory delegates = getPledgeDelegates(_storage, idPledge);
|
||||
|
||||
return Pledge(
|
||||
idPledge,
|
||||
amount,
|
||||
uint64(owner),
|
||||
delegates,
|
||||
uint64(intendedProject),
|
||||
uint64(commitTime),
|
||||
uint64(oldPledge),
|
||||
state
|
||||
);
|
||||
}
|
||||
|
||||
// a constant for when a delegate is requested that is not in the system
|
||||
uint64 constant NOTFOUND = 0xFFFFFFFFFFFFFFFF;
|
||||
|
||||
/// @notice A getter that searches the delegationChain for the level of
|
||||
/// authority a specific delegate has within a Pledge
|
||||
/// @param idPledge The Pledge that will be searched
|
||||
/// @param idDelegate The specified delegate that's searched for
|
||||
/// @return If the delegate chain contains the delegate with the
|
||||
/// `admins` array index `idDelegate` this returns that delegates
|
||||
/// corresponding index in the delegationChain. Otherwise it returns
|
||||
/// the NOTFOUND constant
|
||||
function getDelegateIdx(EternalStorage _storage, uint idPledge, uint64 idDelegate) internal view returns(uint64) {
|
||||
//TODO pack/unpack chain
|
||||
uint length = getPledgeDelegateCount(_storage, idPledge);
|
||||
for (uint i=0; i < length; i++) {
|
||||
if (getPledgeDelegate(_storage, idPledge, i) == idDelegate) return uint64(i);
|
||||
}
|
||||
return NOTFOUND;
|
||||
}
|
||||
|
||||
/// @notice A getter to find how many old "parent" pledges a specific Pledge
|
||||
/// had using a self-referential loop
|
||||
/// @param idOldPledge The Pledge being queried
|
||||
/// @return The number of old "parent" pledges a specific Pledge had
|
||||
function getPledgeLevel(EternalStorage _storage, uint idOldPledge) internal view returns(uint) {
|
||||
if (idOldPledge == 0) return 0;
|
||||
idOldPledge = _storage.stgObjectGetUInt(class, idOldPledge, "oldPledge");
|
||||
return getPledgeLevel(_storage, idOldPledge) + 1; // a loop lookup
|
||||
}
|
||||
|
||||
function getPledgeOwner(EternalStorage _storage, uint idPledge) internal view returns(uint) {
|
||||
return _storage.stgObjectGetUInt(class, idPledge, "owner");
|
||||
}
|
||||
|
||||
function getPledgeDelegate(EternalStorage _storage, uint idPledge, uint index) internal view returns(uint) {
|
||||
return _storage.getUIntValue(keccak256("delegationChain", idPledge, index));
|
||||
}
|
||||
|
||||
function getPledgeOldPledge(EternalStorage _storage, uint idPledge) internal view returns(uint) {
|
||||
return _storage.stgObjectGetUInt(class, idPledge, "oldPledge");
|
||||
}
|
||||
|
||||
function getPledgeAmount(EternalStorage _storage, uint idPledge) internal view returns(uint) {
|
||||
return _storage.stgObjectGetUInt(class, idPledge, "amount");
|
||||
}
|
||||
|
||||
function getPledgeIntendedProject(EternalStorage _storage, uint idPledge) internal view returns(uint) {
|
||||
return _storage.stgObjectGetUInt(class, idPledge, "intendedProject");
|
||||
}
|
||||
|
||||
function getPledgeCommitTime(EternalStorage _storage, uint idPledge) internal view returns(uint) {
|
||||
return _storage.stgObjectGetUInt(class, idPledge, "commitTime");
|
||||
}
|
||||
|
||||
function getPledgeState(EternalStorage _storage, uint idPledge) internal view returns(PledgeState) {
|
||||
return PledgeState(_storage.stgObjectGetUInt(class, idPledge, "state"));
|
||||
}
|
||||
|
||||
function getPledgeDelegates(EternalStorage _storage, uint idPledge) internal view returns(uint64[]) {
|
||||
//TODO pack/unpack chain
|
||||
uint length = getPledgeDelegateCount(_storage, idPledge);
|
||||
uint64[] memory delegates = new uint64[](length);
|
||||
for (uint i=0; i < length; i++) {
|
||||
delegates[i] = uint64(getPledgeDelegate(_storage, idPledge, i));
|
||||
}
|
||||
return delegates;
|
||||
}
|
||||
|
||||
function getPledgeDelegateCount(EternalStorage _storage, uint idPledge) internal view returns(uint) {
|
||||
return _storage.getUIntValue(keccak256("delegationChain", idPledge, "length"));
|
||||
}
|
||||
|
||||
function setPledgeAmount(EternalStorage _storage, uint idPledge, uint amount) internal {
|
||||
_storage.stgObjectSetUInt(class, idPledge, "amount", amount);
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user