-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathEthernaut.sol
75 lines (55 loc) · 2.27 KB
/
Ethernaut.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
pragma solidity ^0.4.18;
import './levels/base/Level.sol';
import 'zeppelin-solidity/contracts/ownership/Ownable.sol';
contract Ethernaut is Ownable {
// ----------------------------------
// Owner interaction
// ----------------------------------
mapping(address => bool) registeredLevels;
mapping(address => string) public players;
// Only registered levels will be allowed to generate and validate level instances.
function registerLevel(Level _level) public onlyOwner {
registeredLevels[_level] = true;
}
// ----------------------------------
// Get/submit level instances
// ----------------------------------
struct EmittedInstanceData {
address player;
Level level;
bool completed;
}
mapping(address => EmittedInstanceData) emittedInstances;
event LevelInstanceCreatedLog(address indexed player, address instance, string nickname);
event LevelCompletedLog(address indexed player, Level level, string nickname);
function register(string _nickname) public returns(bool) {
if(bytes(_nickname).length > 0 && bytes(players[msg.sender]).length == 0) {
players[msg.sender] = _nickname;
return true;
}
return false;
}
function createLevelInstance(Level _level) public payable {
// Ensure level is registered.
require(registeredLevels[_level]);
// Get level factory to create an instance.
address instance = _level.createInstance.value(msg.value)(msg.sender);
// Store emitted instance relationship with player and level.
emittedInstances[instance] = EmittedInstanceData(msg.sender, _level, false);
// Retrieve created instance via logs.
LevelInstanceCreatedLog(msg.sender, instance, players[msg.sender]);
}
function submitLevelInstance(address _instance) public {
// Get player and level.
EmittedInstanceData storage data = emittedInstances[_instance];
require(data.player == msg.sender); // instance was emitted for this player
require(data.completed == false); // not already submitted
// Have the level check the instance.
if(data.level.validateInstance(_instance, msg.sender)) {
// Register instance as completed.
data.completed = true;
// Notify success via logs.
LevelCompletedLog(msg.sender, data.level, players[msg.sender]);
}
}
}