Skip to content

Commit

Permalink
fix review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
pythonberg1997 committed Dec 8, 2023
1 parent db24950 commit 698705a
Show file tree
Hide file tree
Showing 8 changed files with 190 additions and 60 deletions.
91 changes: 86 additions & 5 deletions abi/stakecredit.abi
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,25 @@
],
"stateMutability": "nonpayable"
},
{
"type": "function",
"name": "claimableUnbondRequest",
"inputs": [
{
"name": "delegator",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"type": "function",
"name": "decimals",
Expand Down Expand Up @@ -270,6 +289,11 @@
"name": "delegator",
"type": "address",
"internalType": "address"
},
{
"name": "number",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
Expand All @@ -294,6 +318,44 @@
],
"stateMutability": "view"
},
{
"type": "function",
"name": "pendingUnbondRequest",
"inputs": [
{
"name": "delegator",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"type": "function",
"name": "rewardRecord",
"inputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"type": "function",
"name": "slash",
Expand Down Expand Up @@ -339,6 +401,25 @@
],
"stateMutability": "view"
},
{
"type": "function",
"name": "totalPooledBNBRecord",
"inputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"type": "function",
"name": "totalSupply",
Expand Down Expand Up @@ -466,11 +547,6 @@
"internalType": "uint256"
}
]
},
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
Expand Down Expand Up @@ -699,6 +775,11 @@
"name": "OutOfBounds",
"inputs": []
},
{
"type": "error",
"name": "RequestExisted",
"inputs": []
},
{
"type": "error",
"name": "TransferFailed",
Expand Down
61 changes: 52 additions & 9 deletions contracts/BC_fusion/StakeCredit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ contract StakeCredit is System, Initializable, ReentrancyGuardUpgradeable, ERC20
error NoUnbondRequest();
// @notice signature: 0x0f363824
error NoClaimableUnbondRequest();
// @notice signature: 0xb19e9115
error RequestExisted();

/*----------------- storage -----------------*/
address public validator; // validator's operator address
Expand All @@ -49,6 +51,11 @@ contract StakeCredit is System, Initializable, ReentrancyGuardUpgradeable, ERC20
// delegator address => personal unbond sequence
mapping(address => CountersUpgradeable.Counter) private _unbondSequence;

// day index => receivedReward
mapping(uint256 => uint256) public rewardRecord;
// day index => totalPooledBNB
mapping(uint256 => uint256) public totalPooledBNBRecord;

/*----------------- structs and events -----------------*/
struct UnbondRequest {
uint256 shares;
Expand All @@ -62,6 +69,9 @@ contract StakeCredit is System, Initializable, ReentrancyGuardUpgradeable, ERC20
* @notice only accept BNB from `StakeHub`
*/
receive() external payable onlyStakeHub {
uint256 dayIndex = block.timestamp / 1 days;
totalPooledBNBRecord[dayIndex] = totalPooledBNB;
rewardRecord[dayIndex] += msg.value;
totalPooledBNB += msg.value;
}

Expand Down Expand Up @@ -104,6 +114,9 @@ contract StakeCredit is System, Initializable, ReentrancyGuardUpgradeable, ERC20
uint256 unlockTime = block.timestamp + IStakeHub(STAKE_HUB_ADDR).unbondPeriod();
UnbondRequest memory request = UnbondRequest({ shares: shares, bnbAmount: bnbAmount, unlockTime: unlockTime });
bytes32 hash = keccak256(abi.encodePacked(delegator, _useSequence(delegator)));
// the hash should not exist in the queue
// this will not happen in normal cases
if (_unbondRequests[hash].shares != 0) revert RequestExisted();
_unbondRequests[hash] = request;
_unbondRequestsQueue[delegator].pushBack(hash);
}
Expand Down Expand Up @@ -147,7 +160,6 @@ contract StakeCredit is System, Initializable, ReentrancyGuardUpgradeable, ERC20

// remove from the queue
_unbondRequestsQueue[delegator].popFront();
delete _unbondRequests[hash];

_totalBnbAmount += request.bnbAmount;
--number;
Expand All @@ -169,6 +181,10 @@ contract StakeCredit is System, Initializable, ReentrancyGuardUpgradeable, ERC20
uint256 bnbAmount = msg.value;
uint256 _commission = (bnbAmount * uint256(commissionRate)) / COMMISSION_RATE_BASE;
uint256 _reward = bnbAmount - _commission;

uint256 dayIndex = block.timestamp / 1 days;
totalPooledBNBRecord[dayIndex] = totalPooledBNB;
rewardRecord[dayIndex] += _reward;
totalPooledBNB += _reward;

// mint commission to the validator
Expand Down Expand Up @@ -213,24 +229,51 @@ contract StakeCredit is System, Initializable, ReentrancyGuardUpgradeable, ERC20
}

/**
* @return the unbond request at _index and the total length of delegator's unbond queue.
* @return the unbond request at _index.
*/
function unbondRequest(address delegator, uint256 _index) public view returns (UnbondRequest memory, uint256) {
function unbondRequest(address delegator, uint256 _index) public view returns (UnbondRequest memory) {
bytes32 hash = _unbondRequestsQueue[delegator].at(_index);
return (_unbondRequests[hash], _unbondRequestsQueue[delegator].length());
return _unbondRequests[hash];
}

/**
* @return the total length of delegator's pending unbond queue.
*/
function pendingUnbondRequest(address delegator) public view returns (uint256) {
return _unbondRequestsQueue[delegator].length();
}

/**
* @return the total amount of BNB locked in the unbond queue.
* @return the total number of delegator's claimable unbond requests.
*/
function lockedBNBs(address delegator) public view returns (uint256) {
function claimableUnbondRequest(address delegator) public view returns (uint256) {
uint256 length = _unbondRequestsQueue[delegator].length();
if (length == 0) {
return 0;
uint256 count;
for (uint256 i; i < length; ++i) {
bytes32 hash = _unbondRequestsQueue[delegator].front();
UnbondRequest memory request = _unbondRequests[hash];
if (block.timestamp >= request.unlockTime) {
++count;
} else {
break;
}
}
return count;
}

/**
* @return the sum of first `number` requests' BNB locked in delegator's unbond queue.
*/
function lockedBNBs(address delegator, uint256 number) public view returns (uint256) {
// number == 0 means all
// number should not exceed the length of the queue
if (_unbondRequestsQueue[delegator].length() == 0) revert NoUnbondRequest();
number = (number == 0 || number > _unbondRequestsQueue[delegator].length())
? _unbondRequestsQueue[delegator].length()
: number;

uint256 _totalBnbAmount;
for (uint256 i; i < length; ++i) {
for (uint256 i; i < number; ++i) {
bytes32 hash = _unbondRequestsQueue[delegator].front();
UnbondRequest memory request = _unbondRequests[hash];
_totalBnbAmount += request.bnbAmount;
Expand Down
18 changes: 7 additions & 11 deletions contracts/BC_fusion/StakeHub.sol
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,6 @@ contract StakeHub is System, Initializable {
mapping(address => address) private _consensusToOperator;
// slash key => slash jail time
mapping(bytes32 => uint256) private _felonyRecords;
// operator address => day index => receivedReward
mapping(address => mapping(uint256 => uint256)) private _rewardRecords;
// operator address => day index => totalPooledBNB
mapping(address => mapping(uint256 => uint256)) private _totalPooledBNBRecords;

// legacy addresses of BC
mapping(address => bool) private _legacyConsensusAddress;
Expand Down Expand Up @@ -557,10 +553,6 @@ contract StakeHub is System, Initializable {
return;
}

uint256 dayIndex = block.timestamp / 1 days;
_rewardRecords[operatorAddress][dayIndex] = msg.value;
_totalPooledBNBRecords[operatorAddress][dayIndex] = IStakeCredit(valInfo.creditContract).totalPooledBNB();

IStakeCredit(valInfo.creditContract).distributeReward{ value: msg.value }(valInfo.commission.rate);
emit RewardDistributed(operatorAddress, msg.value);
}
Expand Down Expand Up @@ -592,6 +584,7 @@ contract StakeHub is System, Initializable {
Validator storage valInfo = _validators[operatorAddress];

uint256 dayIndex = block.timestamp / 1 days;
// This is to prevent many honest validators being slashed at the same time because of implementation bugs
if (_felonyMap[dayIndex] >= felonyPerDay) revert NoMoreFelonyToday();
_felonyMap[dayIndex] += 1;

Expand All @@ -614,7 +607,8 @@ contract StakeHub is System, Initializable {
if (!_validatorSet.contains(operatorAddress)) revert ValidatorNotExist(); // should never happen
Validator storage valInfo = _validators[operatorAddress];

uint256 dayIndex = block.timestamp;
uint256 dayIndex = block.timestamp / 1 days;
// This is to prevent many honest validators being slashed at the same time because of implementation bugs
if (_felonyMap[dayIndex] >= felonyPerDay) revert NoMoreFelonyToday();
_felonyMap[dayIndex] += 1;

Expand Down Expand Up @@ -748,7 +742,8 @@ contract StakeHub is System, Initializable {
* @return the validator's reward of the day
*/
function getValidatorRewardRecord(address operatorAddress, uint256 dayIndex) external view returns (uint256) {
return _rewardRecords[operatorAddress][dayIndex];
if (!_validatorSet.contains(operatorAddress)) revert ValidatorNotExist();
return IStakeCredit(_validators[operatorAddress].creditContract).rewardRecord(dayIndex);
}

/**
Expand All @@ -758,7 +753,8 @@ contract StakeHub is System, Initializable {
address operatorAddress,
uint256 dayIndex
) external view returns (uint256) {
return _totalPooledBNBRecords[operatorAddress][dayIndex];
if (!_validatorSet.contains(operatorAddress)) revert ValidatorNotExist();
return IStakeCredit(_validators[operatorAddress].creditContract).totalPooledBNBRecord(dayIndex);
}

/**
Expand Down
2 changes: 2 additions & 0 deletions contracts/BC_fusion/interface/IStakeCredit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ interface IStakeCredit {
function balanceOf(address delegator) external view returns (uint256);
function totalSupply() external view returns (uint256);
function getPooledBNB(address account) external view returns (uint256);
function rewardRecord(uint256 dayIndex) external view returns (uint256);
function totalPooledBNBRecord(uint256 dayIndex) external view returns (uint256);
}
3 changes: 0 additions & 3 deletions contracts/BSCValidatorSet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -256,9 +256,6 @@ contract BSCValidatorSet is IBSCValidatorSet, System, IParamSubscriber, IApplica
// if staking channel is not closed, store the migrated validator set and return
if (ICrossChain(CROSS_CHAIN_CONTRACT_ADDR).registeredContractChannelMap(VALIDATOR_CONTRACT_ADDR, STAKING_CHANNELID)) {
uint256 newLength = _validatorSet.length;
if (newLength == 0) {
return;
}
uint256 oldLength = _tmpMigratedValidatorSet.length;
if (oldLength > newLength) {
for (uint256 i = newLength; i < oldLength; ++i) {
Expand Down
2 changes: 0 additions & 2 deletions contracts/SlashIndicator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,6 @@ contract SlashIndicator is ISlashIndicator,System,IParamSubscriber, IApplication
}
}

//TODO: add onlyRelayer
function submitFinalityViolationEvidence(FinalityEvidence memory _evidence) public onlyInit {
require(enableMaliciousVoteSlash, "malicious vote slash not enabled");
if (finalitySlashRewardRatio == 0) {
Expand Down Expand Up @@ -269,7 +268,6 @@ contract SlashIndicator is ISlashIndicator,System,IParamSubscriber, IApplication
}
}

//TODO: add onlyRelayer
function submitDoubleSignEvidence(bytes memory header1, bytes memory header2) public onlyInit {
require(header1.length != 0 && header2.length != 0, "empty header");

Expand Down
Loading

0 comments on commit 698705a

Please sign in to comment.