2017-06-06 17:40:14 +00:00
|
|
|
pragma solidity ^0.4.11;
|
2018-01-25 16:31:13 +00:00
|
|
|
|
2017-10-24 04:09:56 +00:00
|
|
|
/*
|
|
|
|
Copyright 2017, Jordi Baylina
|
2017-12-04 01:18:31 +00:00
|
|
|
Contributors: Adrià Massanet <adria@codecontext.io>, RJ Ewing, Griff
|
|
|
|
Green, Arthur Lunn
|
2017-10-24 04:09:56 +00:00
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
2017-06-06 17:40:14 +00:00
|
|
|
|
2017-09-13 12:41:08 +00:00
|
|
|
import "./ILiquidPledgingPlugin.sol";
|
2018-02-10 14:14:52 +00:00
|
|
|
// import "giveth-common-contracts/contracts/Escapable.sol";
|
|
|
|
import "./EscapableApp.sol";
|
2018-01-17 01:20:07 +00:00
|
|
|
import "./PledgeAdmins.sol";
|
2018-01-19 18:33:58 +00:00
|
|
|
import "./Pledges.sol";
|
2017-09-13 12:41:08 +00:00
|
|
|
|
2017-12-04 01:18:31 +00:00
|
|
|
/// @dev This is an interface for `LPVault` which serves as a secure storage for
|
|
|
|
/// the ETH that backs the Pledges, only after `LiquidPledging` authorizes
|
|
|
|
/// payments can Pledges be converted for ETH
|
2018-02-10 14:14:52 +00:00
|
|
|
interface ILPVault {
|
2018-01-15 22:36:17 +00:00
|
|
|
function authorizePayment(bytes32 _ref, address _dest, uint _amount) public;
|
|
|
|
function () public payable;
|
2017-07-13 17:12:45 +00:00
|
|
|
}
|
2017-06-06 17:40:14 +00:00
|
|
|
|
2017-10-24 04:09:56 +00:00
|
|
|
/// @dev `LiquidPledgingBase` is the base level contract used to carry out
|
2017-12-04 01:18:31 +00:00
|
|
|
/// liquidPledging's most basic functions, mostly handling and searching the
|
2017-11-23 15:00:28 +00:00
|
|
|
/// data structures
|
2018-02-10 14:14:52 +00:00
|
|
|
contract LiquidPledgingBase is PledgeAdmins, Pledges, EscapableApp {
|
2017-06-06 17:40:14 +00:00
|
|
|
|
2018-02-10 14:14:52 +00:00
|
|
|
ILPVault public vault;
|
2018-01-25 16:31:13 +00:00
|
|
|
|
2017-11-23 15:00:28 +00:00
|
|
|
/////////////
|
2017-06-06 17:40:14 +00:00
|
|
|
// Modifiers
|
2017-11-23 15:00:28 +00:00
|
|
|
/////////////
|
|
|
|
|
|
|
|
/// @dev The `vault`is the only addresses that can call a function with this
|
|
|
|
/// modifier
|
2017-06-06 17:40:14 +00:00
|
|
|
modifier onlyVault() {
|
2017-07-13 17:12:45 +00:00
|
|
|
require(msg.sender == address(vault));
|
2017-06-06 17:40:14 +00:00
|
|
|
_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-11-23 15:00:28 +00:00
|
|
|
///////////////
|
2017-06-06 17:40:14 +00:00
|
|
|
// Constructor
|
2017-11-23 15:00:28 +00:00
|
|
|
///////////////
|
2017-06-06 17:40:14 +00:00
|
|
|
|
2018-02-12 22:55:11 +00:00
|
|
|
function initialize(address _escapeHatchDestination) onlyInit public {
|
2018-02-10 14:14:52 +00:00
|
|
|
require(false); // overload the EscapableApp
|
|
|
|
}
|
|
|
|
|
|
|
|
/// @param _vault The vault where the ETH backing the pledges is stored
|
|
|
|
/// @param _escapeHatchDestination The address of a safe location (usu a
|
|
|
|
/// Multisig) to send the ether held in this contract; if a neutral address
|
|
|
|
/// is required, the WHG Multisig is an option:
|
|
|
|
/// 0x8Ff920020c8AD673661c8117f2855C384758C572
|
2018-02-12 22:55:11 +00:00
|
|
|
function initialize(address _vault, address _escapeHatchDestination) onlyInit public {
|
|
|
|
super.initialize(_escapeHatchDestination);
|
2018-02-10 14:14:52 +00:00
|
|
|
require(_vault != 0x0);
|
|
|
|
|
|
|
|
vault = ILPVault(_vault);
|
2018-02-12 22:55:11 +00:00
|
|
|
|
|
|
|
admins.length = 1; // we reserve the 0 admin
|
|
|
|
pledges.length = 1; // we reserve the 0 pledge
|
2018-02-10 14:14:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-01-25 16:31:13 +00:00
|
|
|
/////////////////////////////
|
2017-06-06 17:40:14 +00:00
|
|
|
// Public constant functions
|
2018-01-25 16:31:13 +00:00
|
|
|
/////////////////////////////
|
2017-10-27 19:09:55 +00:00
|
|
|
|
2017-11-23 15:00:28 +00:00
|
|
|
/// @notice Getter to find Delegate w/ the Pledge ID & the Delegate index
|
|
|
|
/// @param idPledge The id number representing the pledge being queried
|
|
|
|
/// @param idxDelegate The index number for the delegate in this Pledge
|
2018-02-10 14:14:52 +00:00
|
|
|
function getPledgeDelegate(uint64 idPledge, uint64 idxDelegate) public view returns(
|
|
|
|
uint64 idDelegate,
|
2017-06-06 17:40:14 +00:00
|
|
|
address addr,
|
|
|
|
string name
|
|
|
|
) {
|
2018-02-10 14:14:52 +00:00
|
|
|
Pledge storage p = _findPledge(idPledge);
|
|
|
|
idDelegate = p.delegationChain[idxDelegate - 1];
|
|
|
|
PledgeAdmin storage delegate = _findAdmin(idDelegate);
|
|
|
|
addr = delegate.addr;
|
|
|
|
name = delegate.name;
|
2017-06-06 17:40:14 +00:00
|
|
|
}
|
|
|
|
|
2018-01-25 16:31:13 +00:00
|
|
|
////////////////////
|
|
|
|
// Internal methods
|
|
|
|
////////////////////
|
2017-06-06 17:40:14 +00:00
|
|
|
|
2018-01-25 16:31:13 +00:00
|
|
|
/// @notice A check to see if the msg.sender is the owner or the
|
|
|
|
/// plugin contract for a specific Admin
|
2018-02-10 14:14:52 +00:00
|
|
|
/// @param a The admin being checked
|
|
|
|
// function _checkAdminOwner(PledgeAdmin a) internal constant {
|
|
|
|
// require(msg.sender == a.addr || msg.sender == address(a.plugin));
|
|
|
|
// }
|
2017-11-23 15:00:28 +00:00
|
|
|
|
|
|
|
/// @notice A getter to find the longest commitTime out of the owner and all
|
|
|
|
/// the delegates for a specified pledge
|
2017-12-05 20:47:38 +00:00
|
|
|
/// @param p The Pledge being queried
|
2017-11-23 15:00:28 +00:00
|
|
|
/// @return The maximum commitTime out of the owner and all the delegates
|
2018-02-10 14:14:52 +00:00
|
|
|
function _maxCommitTime(Pledge p) internal view returns(uint64 commitTime) {
|
|
|
|
PledgeAdmin storage a = _findAdmin(p.owner);
|
|
|
|
commitTime = a.commitTime; // start with the owner's commitTime
|
2017-09-13 12:41:08 +00:00
|
|
|
|
2018-01-25 16:31:13 +00:00
|
|
|
for (uint i = 0; i < p.delegationChain.length; i++) {
|
2018-02-10 14:14:52 +00:00
|
|
|
a = _findAdmin(p.delegationChain[i]);
|
2017-11-23 15:00:28 +00:00
|
|
|
|
|
|
|
// If a delegate's commitTime is longer, make it the new commitTime
|
2018-02-10 14:14:52 +00:00
|
|
|
if (a.commitTime > commitTime) {
|
|
|
|
commitTime = a.commitTime;
|
2018-01-25 16:31:13 +00:00
|
|
|
}
|
2017-09-13 12:41:08 +00:00
|
|
|
}
|
|
|
|
}
|
2017-08-18 16:47:22 +00:00
|
|
|
|
2017-11-23 15:00:28 +00:00
|
|
|
/// @notice A getter to find the oldest pledge that hasn't been canceled
|
|
|
|
/// @param idPledge The starting place to lookup the pledges
|
|
|
|
/// @return The oldest idPledge that hasn't been canceled (DUH!)
|
2018-02-10 14:14:52 +00:00
|
|
|
function _getOldestPledgeNotCanceled(
|
2018-01-17 01:20:07 +00:00
|
|
|
uint64 idPledge
|
2018-01-19 18:33:58 +00:00
|
|
|
) internal view returns(uint64)
|
2018-01-17 01:20:07 +00:00
|
|
|
{
|
2018-01-25 16:31:13 +00:00
|
|
|
if (idPledge == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
2017-11-16 23:15:32 +00:00
|
|
|
|
2018-02-10 14:14:52 +00:00
|
|
|
Pledge storage p = _findPledge(idPledge);
|
|
|
|
PledgeAdmin storage admin = _findAdmin(p.owner);
|
|
|
|
|
|
|
|
if (admin.adminType == PledgeAdminType.Giver) {
|
2018-01-25 16:31:13 +00:00
|
|
|
return idPledge;
|
|
|
|
}
|
2017-11-16 23:15:32 +00:00
|
|
|
|
2018-02-10 14:14:52 +00:00
|
|
|
assert(admin.adminType == PledgeAdminType.Project);
|
|
|
|
if (!_isProjectCanceled(p.owner)) {
|
2018-01-25 16:31:13 +00:00
|
|
|
return idPledge;
|
2017-11-16 23:15:32 +00:00
|
|
|
}
|
2018-01-25 16:31:13 +00:00
|
|
|
|
2018-02-10 14:14:52 +00:00
|
|
|
return _getOldestPledgeNotCanceled(p.oldPledge);
|
2017-11-16 23:15:32 +00:00
|
|
|
}
|
2017-06-06 17:40:14 +00:00
|
|
|
}
|