-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathDigitalDollarRetainerRegistry.sol
116 lines (95 loc) · 5.95 KB
/
DigitalDollarRetainerRegistry.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/*
|| DIGITAL DOLLAR RETAINER REGISTRY (DDRR) ||
DEAR MSG.SENDER(S):
/ DDRR is a project in beta.
// Please audit and use at your own risk.
/// Entry into DDRR shall not create an attorney/client relationship.
//// Likewise, DDRR should not be construed as legal advice or replacement for professional counsel.
///// STEAL THIS C0D3SL4W ( . . . But tipping is also cool! See tip0E function below ;-0)
|| Open, ESQ LLC/DAO ||
*/
pragma solidity 0.5.9;
/***************
DDRR CONTRACT
***************/
contract DigitalDollarRetainerRegistry {
mapping (uint256 => DDR) public rddr; // **mapping registered rddr call numbers**
struct DDR {
address client; // **client ethereum address**
address provider; // **ethereum address that receives payments in exchange for goods or services**
ERC20 ddrToken; // **ERC-20 digital token address used to transfer value on ethereum under rddr / e.g., DAI 'digital dollar' - 0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359**
string deliverable; // **goods or services (deliverable) retained for benefit of ethereum payments**
string governingLawForum; // **choice of law and forum for retainer relationship (or similar legal description)**
uint256 ddrNumber; // **rddr number generated on registration / identifies rddr for payDDR calls**
uint256 timeStamp; // **block.timestamp of registration used to calculate retainerTermination UnixTime**
uint256 retainerDuration; // **duration of rddr in seconds**
uint256 retainerTermination; // **termination date of rddr in UnixTime**
uint256 deliverableRate; // **rate for rddr deliverables in digital dollar wei amount / 1 = 1000000000000000000**
uint256 paid; // **tracking amount of designated ERC-20 paid under rddr in wei amount**
uint256 payCap; // **cap in wei amount to limit payments under rddr**;
}
// **template legal wrapper stating general human-readable DDR terms for rddr to inherit**
string public ddrTerms = "|| Establishing a digital retainer hereby as [[ddrNumber]] and acknowledging mutual consideration and agreement, Client, identified by ethereum address 0x[[client]], commits to perform under this digital payment transactional script capped at $[[payCap]] digital dollar value denominated in 0x[[ddrToken]] for benefit of Provider, identified by ethereum address 0x[[provider]], in exchange for prompt satisfaction of the following, [[deliverable]], to Client by Provider upon scripted payments set at the rate of $[[deliverableRate]] per deliverable, with such retainer relationship not to exceed [[retainerDuration]] seconds and to be governed by choice of [[governingLawForum]] law and 'either/or' arbitration rules in [[governingLawForum]]. ||";
uint256 public RDDR; // **number of DDRs registered hereby**
event Registered(address indexed client, address indexed provider); // **triggered on successful registration**
event Paid(uint256 ratePaid, uint256 totalPaid, address indexed client); // **triggered on successful rddr payments**
function registerDDR(
address client,
address provider,
ERC20 ddrToken,
string memory deliverable,
string memory governingLawForum,
uint256 retainerDuration,
uint256 deliverableRate,
uint256 payCap) public {
require(deliverableRate <= payCap, "constructor: deliverableRate cannot exceed payCap"); // **program safety check / economics**
uint256 ddrNumber = RDDR + 1; // **reflects new rddr value for tracking payments**
uint256 paid = 0; // **initial zero value for rddr**
uint256 timeStamp = now; // **block.timestamp of rddr**
uint256 retainerTermination = timeStamp + retainerDuration; // **rddr termination date in UnixTime**
RDDR = RDDR + 1; // counts new entry to RDDR
rddr[ddrNumber] = DDR( // populate rddr data
client,
provider,
ddrToken,
deliverable,
governingLawForum,
ddrNumber,
timeStamp,
retainerDuration,
retainerTermination,
deliverableRate,
paid,
payCap);
emit Registered(client, provider);
}
function payDDR(uint256 ddrNumber) public { // **forwards approved ddrToken deliverableRate amount to provider ethereum address**
DDR storage ddr = rddr[ddrNumber]; // **retrieve rddr data**
require (now <= ddr.retainerTermination); // **program safety check / time**
require(address(msg.sender) == ddr.client); // program safety check / authorization
require(ddr.paid + ddr.deliverableRate <= ddr.payCap, "payDAI: payCap exceeded"); // **program safety check / economics**
ddr.ddrToken.transferFrom(msg.sender, ddr.provider, ddr.deliverableRate); // **executes ERC-20 transfer**
ddr.paid = ddr.paid + ddr.deliverableRate; // **tracks amount paid under rddr**
emit Paid(ddr.deliverableRate, ddr.paid, msg.sender);
}
function tipOpenESQ() public payable { // **tip Open, ESQ LLC/DAO ether (Ξ) value for legal engineering R+D / LEETH**
0xBBE222Ef97076b786f661246232E41BE0DFf6cc4.transfer(msg.value); // forwards value to OE-DAO ethereum address
}
}
/***************
ERC-20 CONTRACT - DDRR REFERENCE ATTACHMENT
***************/
/**
* @title ERC-20 Contract
* @dev see https://github.com/ethereum/EIPs/issues/20
*/
contract ERC20 {
uint256 public totalSupply;
function balanceOf(address who) public view returns (uint256);
function transfer(address to, uint256 value) public returns (bool);
function allowance(address owner, address spender) public view returns (uint256);
function transferFrom(address from, address to, uint256 value) public returns (bool);
function approve(address spender, uint256 value) public returns (bool);
event Approval(address indexed owner, address indexed spender, uint256 value);
event Transfer(address indexed from, address indexed to, uint256 value);
}