mirror of
https://github.com/logos-messaging/bootstrap-enr-incentivization.git
synced 2026-01-07 15:23:08 +00:00
feat: init
v1.6.0
This commit is contained in:
parent
45c1ba3560
commit
0a5bf46076
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[submodule "lib/forge-std"]
|
||||||
|
path = lib/forge-std
|
||||||
|
url = https://github.com/foundry-rs/forge-std
|
||||||
|
[submodule "lib/openzeppelin-contracts"]
|
||||||
|
path = lib/openzeppelin-contracts
|
||||||
|
url = https://github.com/openzeppelin/openzeppelin-contracts
|
||||||
@ -1,6 +1,3 @@
|
|||||||
[profile.default]
|
[profile.default]
|
||||||
src = "src"
|
libs = ['node_modules', 'lib']
|
||||||
out = "out"
|
test = 'test'
|
||||||
libs = ["lib"]
|
|
||||||
|
|
||||||
# See more config options https://github.com/foundry-rs/foundry/tree/master/config
|
|
||||||
1
lib/forge-std
Submodule
1
lib/forge-std
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 74cfb77e308dd188d2f58864aaf44963ae6b88b1
|
||||||
1
lib/openzeppelin-contracts
Submodule
1
lib/openzeppelin-contracts
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit e50c24f5839db17f46991478384bfda14acfb830
|
||||||
84
src/Bootstrap.sol
Normal file
84
src/Bootstrap.sol
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
// SPDX-License-Identifier: UNLICENSED
|
||||||
|
pragma solidity ^0.8.13;
|
||||||
|
|
||||||
|
import "openzeppelin-contracts/contracts/access/Ownable.sol";
|
||||||
|
import "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
|
||||||
|
|
||||||
|
contract Bootstrap is Ownable {
|
||||||
|
IERC20 public immutable token;
|
||||||
|
|
||||||
|
uint256 public immutable rewardRate;
|
||||||
|
|
||||||
|
mapping(uint8 => mapping(uint256 => bytes)) enrIndex;
|
||||||
|
|
||||||
|
mapping(uint8 => uint256) shardEnrIndex;
|
||||||
|
|
||||||
|
mapping(uint8 => mapping(uint256 => mapping(bytes => bool))) public shardEnrs;
|
||||||
|
|
||||||
|
uint8 public immutable shardCount;
|
||||||
|
|
||||||
|
mapping(address => bool) public arbiters;
|
||||||
|
|
||||||
|
struct Challenge {
|
||||||
|
uint256 uptime;
|
||||||
|
address arbiter;
|
||||||
|
}
|
||||||
|
|
||||||
|
modifier onlyArbiter() {
|
||||||
|
require(arbiters[msg.sender] == true, "Arbiter: you aren't");
|
||||||
|
_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// map epoch => shard => enr => uptime struct
|
||||||
|
mapping(uint256 => mapping(uint8 => mapping(uint256 => mapping(bytes => Challenge)))) public challenges;
|
||||||
|
|
||||||
|
event NewEnr(uint8 shardId, bytes enr);
|
||||||
|
event RemovedEnr(uint8 shardId, bytes enr, Challenge challenge);
|
||||||
|
|
||||||
|
constructor(address _token, uint8 _shardCount, address[] memory _arbiters, uint256 _rewardRate) {
|
||||||
|
token = IERC20(_token);
|
||||||
|
shardCount = _shardCount;
|
||||||
|
for (uint8 i = 0; i < _arbiters.length; ++i) {
|
||||||
|
arbiters[_arbiters[i]] = true;
|
||||||
|
}
|
||||||
|
rewardRate = _rewardRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
function registerEnr(uint8 shard, bytes memory enr) external {
|
||||||
|
require(shard <= shardCount, "shard invalid");
|
||||||
|
|
||||||
|
shardEnrs[shard][shardEnrIndex[shard]][enr] = true;
|
||||||
|
++shardEnrIndex[shard];
|
||||||
|
|
||||||
|
emit NewEnr(shard, enr);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getEnrForShard(uint8 shard) public view returns (bytes[] memory) {
|
||||||
|
uint256 shardSize = shardEnrIndex[shard];
|
||||||
|
bytes[] memory t = new bytes[](shardSize);
|
||||||
|
for (uint256 i = 0; i < shardSize; i++) {
|
||||||
|
bytes memory enr = enrIndex[shard][i];
|
||||||
|
t[i] = enr;
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
function challengeEnrUptime(uint8 shard, bytes memory enr, uint256 uptime) public onlyArbiter {
|
||||||
|
uint256 epoch = block.number % 10; // todo define epochs
|
||||||
|
challenges[epoch][shard][shardEnrIndex[shard]][enr] = Challenge({uptime: uptime, arbiter: msg.sender});
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeEnr(uint256 epoch, uint8 shard, bytes memory enr) public onlyOwner {
|
||||||
|
Challenge storage c = challenges[epoch][shard][shardEnrIndex[shard]][enr];
|
||||||
|
require(c.uptime >= 0, "RemoveEnr: 0 uptime");
|
||||||
|
require(c.arbiter != address(0), "RemoveEnr: 0 address");
|
||||||
|
|
||||||
|
require(token.balanceOf(address(this)) >= rewardRate, "RemoveEnr: no balance");
|
||||||
|
|
||||||
|
shardEnrs[shard][shardEnrIndex[shard]][enr] = false;
|
||||||
|
emit RemovedEnr(shard, enr, c);
|
||||||
|
|
||||||
|
// add balance to arbiter's
|
||||||
|
token.transfer(c.arbiter, rewardRate);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,14 +0,0 @@
|
|||||||
// SPDX-License-Identifier: UNLICENSED
|
|
||||||
pragma solidity ^0.8.13;
|
|
||||||
|
|
||||||
contract Counter {
|
|
||||||
uint256 public number;
|
|
||||||
|
|
||||||
function setNumber(uint256 newNumber) public {
|
|
||||||
number = newNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
function increment() public {
|
|
||||||
number++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
21
test/Bootstrap.t.sol
Normal file
21
test/Bootstrap.t.sol
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// SPDX-License-Identifier: UNLICENSED
|
||||||
|
pragma solidity ^0.8.13;
|
||||||
|
|
||||||
|
import "openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";
|
||||||
|
import "forge-std/Test.sol";
|
||||||
|
import "../src/Bootstrap.sol";
|
||||||
|
|
||||||
|
contract BootstrapTest is Test {
|
||||||
|
ERC20 public token;
|
||||||
|
Bootstrap public bootstrap;
|
||||||
|
|
||||||
|
function setUp() public {
|
||||||
|
token = new ERC20("bootstrap_test", "BOOT");
|
||||||
|
bootstrap = new Bootstrap(address(token));
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSanity() public {
|
||||||
|
assertEq(address(this), bootstrap.owner());
|
||||||
|
assertEq(address(token), address(bootstrap.token()));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,24 +0,0 @@
|
|||||||
// SPDX-License-Identifier: UNLICENSED
|
|
||||||
pragma solidity ^0.8.13;
|
|
||||||
|
|
||||||
import "forge-std/Test.sol";
|
|
||||||
import "../src/Counter.sol";
|
|
||||||
|
|
||||||
contract CounterTest is Test {
|
|
||||||
Counter public counter;
|
|
||||||
|
|
||||||
function setUp() public {
|
|
||||||
counter = new Counter();
|
|
||||||
counter.setNumber(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
function testIncrement() public {
|
|
||||||
counter.increment();
|
|
||||||
assertEq(counter.number(), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function testSetNumber(uint256 x) public {
|
|
||||||
counter.setNumber(x);
|
|
||||||
assertEq(counter.number(), x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user