-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathorchestrator.sol
121 lines (98 loc) · 3.25 KB
/
orchestrator.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
117
118
119
120
121
pragma solidity >=0.4.24;
import "openzeppelin-eth/contracts/ownership/Ownable.sol";
import "./dollarsPolicy.sol";
/*
* Orchestrator
*/
contract Orchestrator is Ownable {
struct Transaction {
bool enabled;
address destination;
bytes data;
}
event TransactionFailed(address indexed destination, uint index, bytes data);
Transaction[] public transactions;
DollarsPolicy public policy;
constructor(address policy_) public {
Ownable.initialize(msg.sender);
policy = DollarsPolicy(policy_);
}
function rebase()
external
{
require(msg.sender == tx.origin); // solhint-disable-line avoid-tx-origin
policy.rebase();
for (uint i = 0; i < transactions.length; i++) {
Transaction storage t = transactions[i];
if (t.enabled) {
bool result =
externalCall(t.destination, t.data);
if (!result) {
emit TransactionFailed(t.destination, i, t.data);
revert("Transaction Failed");
}
}
}
}
function addTransaction(address destination, bytes data)
external
onlyOwner
{
transactions.push(Transaction({
enabled: true,
destination: destination,
data: data
}));
}
function removeTransaction(uint index)
external
onlyOwner
{
require(index < transactions.length, "index out of bounds");
if (index < transactions.length - 1) {
transactions[index] = transactions[transactions.length - 1];
}
transactions.length--;
}
function setTransactionEnabled(uint index, bool enabled)
external
onlyOwner
{
require(index < transactions.length, "index must be in range of stored tx list");
transactions[index].enabled = enabled;
}
function transactionsSize()
external
view
returns (uint256)
{
return transactions.length;
}
function externalCall(address destination, bytes data)
internal
returns (bool)
{
bool result;
assembly { // solhint-disable-line no-inline-assembly
// "Allocate" memory for output
// (0x40 is where "free memory" pointer is stored by convention)
let outputAddress := mload(0x40)
// First 32 bytes are the padded length of data, so exclude that
let dataAddress := add(data, 32)
result := call(
// 34710 is the value that solidity is currently emitting
// It includes callGas (700) + callVeryLow (3, to pay for SUB)
// + callValueTransferGas (9000) + callNewAccountGas
// (25000, in case the destination address does not exist and needs creating)
sub(gas, 34710),
destination,
0, // transfer value in wei
dataAddress,
mload(data), // Size of the input, in bytes. Stored in position 0 of the array.
outputAddress,
0 // Output is ignored, therefore the output size is zero
)
}
return result;
}
}