-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathPassportLogicRegistry.sol
389 lines (309 loc) · 11.5 KB
/
PassportLogicRegistry.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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
// File: openzeppelin-solidity/contracts/ownership/Ownable.sol
pragma solidity ^0.4.24;
/**
* @title Ownable
* @dev The Ownable contract has an owner address, and provides basic authorization control
* functions, this simplifies the implementation of "user permissions".
*/
contract Ownable {
address public owner;
event OwnershipRenounced(address indexed previousOwner);
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
/**
* @dev The Ownable constructor sets the original `owner` of the contract to the sender
* account.
*/
constructor() public {
owner = msg.sender;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
/**
* @dev Allows the current owner to relinquish control of the contract.
* @notice Renouncing to ownership will leave the contract without an owner.
* It will not be possible to call the functions with the `onlyOwner`
* modifier anymore.
*/
function renounceOwnership() public onlyOwner {
emit OwnershipRenounced(owner);
owner = address(0);
}
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param _newOwner The address to transfer ownership to.
*/
function transferOwnership(address _newOwner) public onlyOwner {
_transferOwnership(_newOwner);
}
/**
* @dev Transfers control of the contract to a newOwner.
* @param _newOwner The address to transfer ownership to.
*/
function _transferOwnership(address _newOwner) internal {
require(_newOwner != address(0));
emit OwnershipTransferred(owner, _newOwner);
owner = _newOwner;
}
}
// File: openzeppelin-solidity/contracts/ownership/HasNoEther.sol
pragma solidity ^0.4.24;
/**
* @title Contracts that should not own Ether
* @author Remco Bloemen <remco@2π.com>
* @dev This tries to block incoming ether to prevent accidental loss of Ether. Should Ether end up
* in the contract, it will allow the owner to reclaim this Ether.
* @notice Ether can still be sent to this contract by:
* calling functions labeled `payable`
* `selfdestruct(contract_address)`
* mining directly to the contract address
*/
contract HasNoEther is Ownable {
/**
* @dev Constructor that rejects incoming Ether
* The `payable` flag is added so we can access `msg.value` without compiler warning. If we
* leave out payable, then Solidity will allow inheriting contracts to implement a payable
* constructor. By doing it this way we prevent a payable constructor from working. Alternatively
* we could use assembly to access msg.value.
*/
constructor() public payable {
require(msg.value == 0);
}
/**
* @dev Disallows direct send by setting a default function without the `payable` flag.
*/
function() external {
}
/**
* @dev Transfer all Ether held by the contract to the owner.
*/
function reclaimEther() external onlyOwner {
owner.transfer(address(this).balance);
}
}
// File: openzeppelin-solidity/contracts/token/ERC20/ERC20Basic.sol
pragma solidity ^0.4.24;
/**
* @title ERC20Basic
* @dev Simpler version of ERC20 interface
* See https://github.com/ethereum/EIPs/issues/179
*/
contract ERC20Basic {
function totalSupply() public view returns (uint256);
function balanceOf(address _who) public view returns (uint256);
function transfer(address _to, uint256 _value) public returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
}
// File: openzeppelin-solidity/contracts/token/ERC20/ERC20.sol
pragma solidity ^0.4.24;
/**
* @title ERC20 interface
* @dev see https://github.com/ethereum/EIPs/issues/20
*/
contract ERC20 is ERC20Basic {
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
);
}
// File: openzeppelin-solidity/contracts/token/ERC20/SafeERC20.sol
pragma solidity ^0.4.24;
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure.
* To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
function safeTransfer(
ERC20Basic _token,
address _to,
uint256 _value
)
internal
{
require(_token.transfer(_to, _value));
}
function safeTransferFrom(
ERC20 _token,
address _from,
address _to,
uint256 _value
)
internal
{
require(_token.transferFrom(_from, _to, _value));
}
function safeApprove(
ERC20 _token,
address _spender,
uint256 _value
)
internal
{
require(_token.approve(_spender, _value));
}
}
// File: openzeppelin-solidity/contracts/ownership/CanReclaimToken.sol
pragma solidity ^0.4.24;
/**
* @title Contracts that should be able to recover tokens
* @author SylTi
* @dev This allow a contract to recover any ERC20 token received in a contract by transferring the balance to the contract owner.
* This will prevent any accidental loss of tokens.
*/
contract CanReclaimToken is Ownable {
using SafeERC20 for ERC20Basic;
/**
* @dev Reclaim all ERC20Basic compatible tokens
* @param _token ERC20Basic The address of the token contract
*/
function reclaimToken(ERC20Basic _token) external onlyOwner {
uint256 balance = _token.balanceOf(this);
_token.safeTransfer(owner, balance);
}
}
// File: openzeppelin-solidity/contracts/ownership/HasNoTokens.sol
pragma solidity ^0.4.24;
/**
* @title Contracts that should not own Tokens
* @author Remco Bloemen <remco@2π.com>
* @dev This blocks incoming ERC223 tokens to prevent accidental loss of tokens.
* Should tokens (any ERC20Basic compatible) end up in the contract, it allows the
* owner to reclaim the tokens.
*/
contract HasNoTokens is CanReclaimToken {
/**
* @dev Reject all ERC223 compatible tokens
* @param _from address The address that is transferring the tokens
* @param _value uint256 the amount of the specified token
* @param _data Bytes The data passed from the caller.
*/
function tokenFallback(
address _from,
uint256 _value,
bytes _data
)
external
pure
{
_from;
_value;
_data;
revert();
}
}
// File: contracts/IPassportLogicRegistry.sol
pragma solidity ^0.4.24;
interface IPassportLogicRegistry {
/**
* @dev This event will be emitted every time a new passport logic implementation is registered
* @param version representing the version name of the registered passport logic implementation
* @param implementation representing the address of the registered passport logic implementation
*/
event PassportLogicAdded(string version, address implementation);
/**
* @dev This event will be emitted every time a new passport logic implementation is set as current one
* @param version representing the version name of the current passport logic implementation
* @param implementation representing the address of the current passport logic implementation
*/
event CurrentPassportLogicSet(string version, address implementation);
/**
* @dev Tells the address of the passport logic implementation for a given version
* @param _version to query the implementation of
* @return address of the passport logic implementation registered for the given version
*/
function getPassportLogic(string _version) external view returns (address);
/**
* @dev Tells the version of the current passport logic implementation
* @return version of the current passport logic implementation
*/
function getCurrentPassportLogicVersion() external view returns (string);
/**
* @dev Tells the address of the current passport logic implementation
* @return address of the current passport logic implementation
*/
function getCurrentPassportLogic() external view returns (address);
}
// File: contracts/PassportLogicRegistry.sol
pragma solidity ^0.4.24;
/**
* @title PassportImplRegistry
* @dev This contract works as a registry of passport implementations, it holds the implementations for the registered versions.
*/
contract PassportLogicRegistry is IPassportLogicRegistry, Ownable, HasNoEther, HasNoTokens {
// current passport version/implementation
string internal currentPassportLogicVersion;
address internal currentPassportLogic;
// Mapping of versions to passport implementations
mapping(string => address) internal passportLogicImplementations;
/**
* @dev The PassportImplRegistry constructor sets the current passport version and implementation.
*/
constructor (string _version, address _implementation) public {
_addPassportLogic(_version, _implementation);
_setCurrentPassportLogic(_version);
}
/**
* @dev Registers a new passport version with its logic implementation address
* @param _version representing the version name of the new passport logic implementation to be registered
* @param _implementation representing the address of the new passport logic implementation to be registered
*/
function addPassportLogic(string _version, address _implementation) public onlyOwner {
_addPassportLogic(_version, _implementation);
}
/**
* @dev Tells the address of the passport logic implementation for a given version
* @param _version to query the implementation of
* @return address of the passport logic implementation registered for the given version
*/
function getPassportLogic(string _version) external view returns (address) {
return passportLogicImplementations[_version];
}
/**
* @dev Sets a new passport logic implementation as current one
* @param _version representing the version name of the passport logic implementation to be set as current one
*/
function setCurrentPassportLogic(string _version) public onlyOwner {
_setCurrentPassportLogic(_version);
}
/**
* @dev Tells the version of the current passport logic implementation
* @return version of the current passport logic implementation
*/
function getCurrentPassportLogicVersion() external view returns (string) {
return currentPassportLogicVersion;
}
/**
* @dev Tells the address of the current passport logic implementation
* @return address of the current passport logic implementation
*/
function getCurrentPassportLogic() external view returns (address) {
return currentPassportLogic;
}
function _addPassportLogic(string _version, address _implementation) internal {
require(_implementation != 0x0, "Cannot set implementation to a zero address");
require(passportLogicImplementations[_version] == 0x0, "Cannot replace existing version implementation");
passportLogicImplementations[_version] = _implementation;
emit PassportLogicAdded(_version, _implementation);
}
function _setCurrentPassportLogic(string _version) internal {
require(passportLogicImplementations[_version] != 0x0, "Cannot set non-existing passport logic as current implementation");
currentPassportLogicVersion = _version;
currentPassportLogic = passportLogicImplementations[_version];
emit CurrentPassportLogicSet(currentPassportLogicVersion, currentPassportLogic);
}
}