Skip to content

Commit

Permalink
collator set
Browse files Browse the repository at this point in the history
  • Loading branch information
hujw77 committed May 11, 2024
1 parent cac1de3 commit b2b863e
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 47 deletions.
81 changes: 81 additions & 0 deletions src/collator/CollatorSet.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

contract CollatorSet {
// collator count;
uint256 public count;
// ordered collators.
mapping(address => address) public collators;
// collator => staked ring
mapping(address => uint256) public fundOf;

address private constant HEAD = address(0x1);
address private constant TAIL = address(0x2);

constructor() {
collators[HEAD] = collators[TAIL];
collators[HEAD] = type(uint256).max;
}

function getTopCollators(uint256 k) public view returns (address[] memory) {
address[] memory topCollators = new address[](k);
uint256 len = count;
if (len > k) len = k;
address cur = collators[HEAD];
for (uint256 i = 0; i < k; i++) {
topCollators = cur;
cur = collators[cur];
}
return topCollators;
}

function _addCollator(address cur, uint256 fund, address prev) internal {
require(collators[cur] == address(0));
require(collators[prev] != address(0));
address next = collators[prev];
require(_verifyIndex(prev, fund, next));
fundOf[cur] = fund;
collators[cur] = next;
collators[prev] = cur;
count++;
}

function _removeCollator(address cur, address prev) internal {
require(collators[cur] != address(0));
require(_isPrevCollator(cur, prev));
collators[prev] = collators[cur];
collators[cur] = address(0);
fundOf[cur] = 0;
count--;
}

function _increaseFund(address cur, uint256 fund, address oldPrev, address newPrev) internal {
_updateFund(cur, fundOf[cur] + fund, oldPrev, newPrev);
}

function _reduceFund(address cur, uint256 fund, address oldPrev, address newPrev) internal {
_updateCollator(cur, fundOf[cur] - fund, oldPrev, newPrev);
}

function _updateFund(address cur, uint256 newFund, address oldPrev, address newPrev) internal {
require(collators[cur] != address(0));
require(collators[oldPrev] != address(0));
require(collators[newPrev] != address(0));
if (oldPrev == newPrev) {
require(_isPrevCollator(cur, oldPrev));
require(_verifyIndex(newPrev, newFund, collators[cur]));
fundOf[cur] = newFund;
} else {
_removeCollator(cur, oldPrev);
_addCollator(cur, newFund, newPrev);
}
}

function _verifyIndex(address prev, uint256 newValue, address next) internal view returns (bool) {
return fundOf[prev] >= newValue && newValue >= fundOf[next];
}

function _isPrevCollator(address c, address prev) internal view returns (bool) {
return collators[prev] == c;
}
}
78 changes: 35 additions & 43 deletions src/collator/CollatorStakingHub.sol
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

contract CollatorStakingHub {
// Deposit NFT.
address nft;
import "./CollatorSet.sol";

address stakingPallet;
contract CollatorStakingHub is CollatorSet {
// Deposit NFT.
address public nft;

// ordered collators.
address[] public collators;
address public stakingPallet;

// collator operator => collator
// operator => collator
mapping(address => address) public collatorOf;

uint256 private constant COMMISSION_BASE = 10_000;

// collator => commission
mapping(address => uint256) commissionOf;
mapping(address => uint256) public commissionOf;

struct DepositInfo {
address usr;
Expand All @@ -26,33 +23,34 @@ contract CollatorStakingHub {

mapping(uint256 => DepositInfo) public depositOf;

function _reOrder() internal {
collators.DescByTotalSupply();
}
uint256 private constant COMMISSION_BASE = 10_000;

function createCollator() public {
constructor() CollatorSet() {}

function createCollator(address prev, uint256 commission) public {
address operator = msg.sender;
CollatorStaking collator = new CollatorStaking(operator);
require(collators.add(collator));
require(collatorOf[operator] == address(0));
CollatorStaking cur = new CollatorStaking(operator);
collatorOf[operator] = collator;
_reOrder();
_addCollator(collator, 0, prev);
}

function stake(address operator) public payable {
address usr = msg.sender;
function stake(address operator, address oldPrev, address newPrev) public payable {
address account = msg.sender;
uint256 amount = msg.value;
CollatorStaking collator = collatorOf[operator];
collator.stake(usr, msg.value);
gRING.mint(usr, msg.value);
_reOrder();
collator.stake(account, amount);
// gRING.mint(usr, msg.value);
_increaseFund(collator, amount, oldPrev, newPrev);
}

function unstake(uint256 amount, address operator) public {
function unstake(address operator, uint256 amount, address oldPrev, address newPrev) public {
address usr = msg.sender;
CollatorStaking collator = collatorOf[operator];
collator.withdraw(usr, amount);
usr.transfer(amount);
gRING.burn(usr, amount);
_reOrder();
// gRING.burn(usr, amount);
_reduceFund(collator, amount, oldPrev, newPrev);
}

function claim(address operator) public {
Expand All @@ -61,35 +59,25 @@ contract CollatorStakingHub {
collator.getReward(usr);
}

function stakeNFT(uint256 depositId, address operator) public {
function stakeNFT(address operator, uint256 depositId, address oldPrev, address newPrev) public {
address usr = msg.sender;
nft.transferFrom(usr, address(this), depositId);
uint256 assets = nft.assetsOf(depositId);
CollatorStaking collator = collatorOf[operator];
collator.stake(usr, assets);
depositOf[depositId] = DepositInfo(usr, assets, collator);
gRING.mint(usr, assets);
_reOrder();
// gRING.mint(usr, assets);
_increaseFund(collator, amount, oldPrev, newPrev);
}

function unstakeNFT(uint256 depositId) public {
function unstakeNFT(uint256 depositId, address oldPrev, address newPrev) public {
address usr = msg.sender;
DepositInfo memory info = depositOf[depositId];
require(info.usr == usr);
info.collator.withdraw(usr, info.assets);
nft.transferFrom(address(this), usr, depositId);
gRING.burn(usr, info.assets);
_reOrder();
}

function getTopCollators(uint256 count) public view returns (address[] memory) {
address[] memory topCollators = new address[](count);
uint256 len = collators.length;
if (len > count) len = count;
for (uint256 i = 0; i < count; i++) {
topCollators = collators[i];
}
return topCollators;
// gRING.burn(usr, info.assets);
_reduceFund(collator, amount, oldPrev, newPrev);
}

function distributeReward(address collator) public payable {
Expand All @@ -101,9 +89,13 @@ contract CollatorStakingHub {
collator.notifyRewardAmount{value: rewards - commission_}();
}

function collect(uint256 commission, address collator) public {
function collect(uint256 commission) public {
CollatorStaking collator = collatorOf[msg.sender];
_collect(collator, commission);
}

function _collect(address collator, uint256 commission) internal {
require(commission <= COMMISSION_BASE);
require(msg.sender == collator.operator());
commissionOf[collator] = commission;
}
}
4 changes: 0 additions & 4 deletions src/deposit/Deposit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,6 @@ contract Deposit is ERC721, ERC721Enumerable, ERC721URIStorage, ERC721Burnable {
return depositOf[id].value;
}

function getDeposit(uint256 id) public view returns (uint48, uint48, uint128) {
return (depositOf[id].months, depositOf[id].startAt, depositOf[id].value);
}

function _deposit(address account, uint256 value, uint48 months) internal returns (uint256) {
require(value > 0 && value < type(uint128).max);
require(months <= 36 && months >= 1);
Expand Down

0 comments on commit b2b863e

Please sign in to comment.