-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
18 changed files
with
536 additions
and
290 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,4 +37,4 @@ | |
"publishConfig": { | ||
"access": "public" | ||
} | ||
} | ||
} |
38 changes: 38 additions & 0 deletions
38
packages/solidity/src/xyo-chain/AddressStaking/AddressStaking.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// SPDX-License-Identifier: GPL-3.0 | ||
pragma solidity ^0.8.20; | ||
|
||
import "./interface/IAddressStaking.sol"; | ||
import "../TransferStake/TransferStake.sol"; | ||
import "./AddressStakingProperties.sol"; | ||
import "./Library.sol"; | ||
import "./Internal.sol"; | ||
|
||
contract AddressStaking is | ||
IAddressStaking, | ||
TransferStake, | ||
AddressStakingProperties | ||
{ | ||
// ========== CONSTRUCTOR ========== | ||
|
||
constructor( | ||
uint256 _minWithdrawalBlocks, // The minimum number of blocks that must pass before a pending stake can be withdrawn | ||
address _stakingToken // The token that is used for staking | ||
) | ||
TransferStake(_stakingToken) | ||
AddressStakingProperties(_minWithdrawalBlocks) | ||
{} | ||
|
||
// ========== PUBLIC ========== | ||
|
||
function addStake(address staked, uint256 amount) public returns (bool) { | ||
return _addStake(staked, amount); | ||
} | ||
|
||
function removeStake(uint256 slot) public returns (bool) { | ||
return _removeStake(slot); | ||
} | ||
|
||
function withdrawStake(uint256 slot) public returns (bool) { | ||
return _withdrawStake(slot, this.minWithdrawalBlocks()); | ||
} | ||
} |
55 changes: 55 additions & 0 deletions
55
packages/solidity/src/xyo-chain/AddressStaking/AddressStakingProperties.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// SPDX-License-Identifier: GPL-3.0 | ||
pragma solidity ^0.8.20; | ||
|
||
import "./interface/IAddressStakingProperties.sol"; | ||
import "./Internal.sol"; | ||
|
||
abstract contract AddressStakingProperties is | ||
IAddressStakingProperties, | ||
AddressStakingInternal | ||
{ | ||
uint256 private __minWithdrawalBlocks; | ||
|
||
constructor( | ||
uint256 _minWithdrawalBlocks // The minimum number of blocks that must pass before a pending stake can be withdrawn | ||
) { | ||
__minWithdrawalBlocks = _minWithdrawalBlocks; | ||
} | ||
|
||
function minWithdrawalBlocks() external view returns (uint256) { | ||
return __minWithdrawalBlocks; | ||
} | ||
|
||
function activeByAddressStaked( | ||
address staked | ||
) external view returns (uint256) { | ||
return _stakeAmountByAddressStaked[staked]; | ||
} | ||
|
||
function activeByStaker(address staker) external view returns (uint256) { | ||
return AddressStakingLibrary._calcActiveStake(_accountStakes[staker]); | ||
} | ||
|
||
function pendingByStaker(address staker) external view returns (uint256) { | ||
return AddressStakingLibrary._calcPendingStake(_accountStakes[staker]); | ||
} | ||
|
||
function withdrawnByStalker( | ||
address staker | ||
) external view returns (uint256) { | ||
return | ||
AddressStakingLibrary._calcWithdrawnStake(_accountStakes[staker]); | ||
} | ||
|
||
function active() external view returns (uint256) { | ||
return _totalActiveStake; | ||
} | ||
|
||
function pending() external view returns (uint256) { | ||
return _totalPendingStake; | ||
} | ||
|
||
function withdrawn() external view returns (uint256) { | ||
return _totalWithdrawnStake; | ||
} | ||
} |
97 changes: 97 additions & 0 deletions
97
packages/solidity/src/xyo-chain/AddressStaking/Internal.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// SPDX-License-Identifier: GPL-3.0 | ||
pragma solidity ^0.8.20; | ||
|
||
import "./Library.sol"; | ||
import "./interface/IAddressStakingEvents.sol"; | ||
import "../TransferStake/Abstract.sol"; | ||
import "./interface/IAddressStakingProperties.sol"; | ||
|
||
abstract contract AddressStakingInternal is | ||
IAddressStakingEvents, | ||
AbstractTransferStake | ||
{ | ||
uint256 internal _totalActiveStake; | ||
|
||
uint256 internal _totalPendingStake; | ||
|
||
uint256 internal _totalWithdrawnStake; | ||
|
||
//total amount that is staked for a given address | ||
mapping(address => uint256) internal _stakeAmountByAddressStaked; | ||
|
||
//total amount that is staked by a given staker | ||
mapping(address => uint256) internal _stakeAmountByStaker; | ||
|
||
mapping(address => AddressStakingLibrary.Stake[]) internal _accountStakes; | ||
|
||
function _addStake(address staked, uint256 amount) internal returns (bool) { | ||
require(amount > 0, "Staking: amount must be greater than 0"); | ||
_transferStakeFromSender(amount); | ||
_accountStakes[msg.sender].push( | ||
AddressStakingLibrary.Stake({ | ||
staked: staked, | ||
amount: amount, | ||
addBlock: block.number, | ||
removeBlock: 0, | ||
withdrawBlock: 0 | ||
}) | ||
); | ||
_totalActiveStake += amount; | ||
_stakeAmountByAddressStaked[staked] += amount; | ||
_stakeAmountByStaker[msg.sender] += amount; | ||
emit StakeAdded( | ||
staked, | ||
msg.sender, | ||
_accountStakes[msg.sender].length - 1, | ||
amount | ||
); | ||
return true; | ||
} | ||
|
||
function _removeStake(uint256 slot) internal returns (bool) { | ||
require( | ||
AddressStakingLibrary._isStakeRemovable( | ||
_accountStakes[msg.sender][slot] | ||
), | ||
"Staking: not removable" | ||
); | ||
|
||
uint256 amount = _accountStakes[msg.sender][slot].amount; | ||
address staked = _accountStakes[msg.sender][slot].staked; | ||
|
||
_accountStakes[msg.sender][slot].removeBlock = block.number; | ||
_totalActiveStake -= amount; | ||
_totalPendingStake += amount; | ||
_stakeAmountByAddressStaked[staked] -= amount; | ||
_stakeAmountByStaker[msg.sender] -= amount; | ||
|
||
emit StakeRemoved(staked, msg.sender, slot, amount); | ||
return true; | ||
} | ||
|
||
function _withdrawStake( | ||
uint256 slot, | ||
uint256 minWithdrawalBlocks | ||
) internal returns (bool) { | ||
require( | ||
AddressStakingLibrary._isStakeWithdrawable( | ||
_accountStakes[msg.sender][slot], | ||
minWithdrawalBlocks | ||
), | ||
"Staking: not withdrawable" | ||
); | ||
|
||
uint256 amount = _accountStakes[msg.sender][slot].amount; | ||
address staked = _accountStakes[msg.sender][slot].staked; | ||
|
||
_accountStakes[msg.sender][slot].withdrawBlock = block.number; | ||
_totalPendingStake -= amount; | ||
_totalWithdrawnStake += amount; | ||
|
||
_transferStakeToSender(amount); | ||
|
||
emit StakeWithdrawn(staked, msg.sender, slot, amount); | ||
|
||
return true; | ||
} | ||
} |
105 changes: 105 additions & 0 deletions
105
packages/solidity/src/xyo-chain/AddressStaking/Library.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
// SPDX-License-Identifier: GPL-3.0 | ||
pragma solidity ^0.8.20; | ||
|
||
library AddressStakingLibrary { | ||
struct Stake { | ||
// the thing that is being staked | ||
address staked; | ||
uint256 amount; | ||
uint256 addBlock; | ||
uint256 removeBlock; | ||
uint256 withdrawBlock; | ||
} | ||
|
||
function _activeStakeAmount( | ||
Stake memory stake | ||
) internal pure returns (uint256) { | ||
if ( | ||
stake.addBlock > 0 && | ||
stake.removeBlock == 0 && | ||
stake.withdrawBlock == 0 | ||
) { | ||
return stake.amount; | ||
} else { | ||
return 0; | ||
} | ||
} | ||
|
||
function _pendingStakeAmount( | ||
Stake memory stake | ||
) internal pure returns (uint256) { | ||
if ( | ||
stake.addBlock > 0 && | ||
stake.removeBlock > 0 && | ||
stake.withdrawBlock == 0 | ||
) { | ||
return stake.amount; | ||
} else { | ||
return 0; | ||
} | ||
} | ||
|
||
function _withdrawnStakeAmount( | ||
Stake memory stake | ||
) internal pure returns (uint256) { | ||
if ( | ||
stake.addBlock > 0 && | ||
stake.removeBlock > 0 && | ||
stake.withdrawBlock > 0 | ||
) { | ||
return stake.amount; | ||
} else { | ||
return 0; | ||
} | ||
} | ||
|
||
function _calcActiveStake( | ||
AddressStakingLibrary.Stake[] memory stakes | ||
) internal pure returns (uint256) { | ||
uint total = 0; | ||
for (uint i = 0; i < stakes.length; i++) { | ||
total += _activeStakeAmount(stakes[i]); | ||
} | ||
return total; | ||
} | ||
|
||
function _calcPendingStake( | ||
AddressStakingLibrary.Stake[] memory stakes | ||
) internal pure returns (uint256) { | ||
uint total = 0; | ||
for (uint i = 0; i < stakes.length; i++) { | ||
total += _pendingStakeAmount(stakes[i]); | ||
} | ||
return total; | ||
} | ||
|
||
function _calcWithdrawnStake( | ||
AddressStakingLibrary.Stake[] memory stakes | ||
) internal pure returns (uint256) { | ||
uint total = 0; | ||
for (uint i = 0; i < stakes.length; i++) { | ||
total += _withdrawnStakeAmount(stakes[i]); | ||
} | ||
return total; | ||
} | ||
|
||
function _isStakeRemovable( | ||
AddressStakingLibrary.Stake memory stake | ||
) internal pure returns (bool) { | ||
return | ||
stake.addBlock > 0 && | ||
stake.removeBlock == 0 && | ||
stake.withdrawBlock == 0; | ||
} | ||
|
||
function _isStakeWithdrawable( | ||
AddressStakingLibrary.Stake memory stake, | ||
uint256 minWithdrawalBlocks | ||
) internal view returns (bool) { | ||
return | ||
stake.addBlock > 0 && | ||
stake.removeBlock > 0 && | ||
stake.withdrawBlock == 0 && | ||
block.number > (stake.removeBlock + minWithdrawalBlocks); | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
packages/solidity/src/xyo-chain/AddressStaking/interface/IAddressStaking.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
// SPDX-License-Identifier: GPL-3.0 | ||
pragma solidity ^0.8.20; | ||
|
||
import "./IAddressStakingProperties.sol"; | ||
import "./IAddressStakingFunctions.sol"; | ||
import "./IAddressStakingEvents.sol"; | ||
|
||
interface IAddressStaking is | ||
IAddressStakingProperties, | ||
IAddressStakingFunctions, | ||
IAddressStakingEvents | ||
{} |
28 changes: 28 additions & 0 deletions
28
packages/solidity/src/xyo-chain/AddressStaking/interface/IAddressStakingEvents.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// SPDX-License-Identifier: GPL-3.0 | ||
pragma solidity ^0.8.20; | ||
|
||
interface IAddressStakingEvents { | ||
// This is when a stake is added to the staking contract | ||
event StakeAdded( | ||
address indexed staked, | ||
address indexed by, | ||
uint256 indexed slot, | ||
uint256 amount | ||
); | ||
|
||
// This is when a specific stake is requested for removal. It removes it from the staked amount but does not actually remove the XYO from the staking contract | ||
event StakeRemoved( | ||
address indexed staked, | ||
address indexed by, | ||
uint256 indexed slot, | ||
uint256 amount | ||
); | ||
|
||
// This is when actual XYO is removed from the staking contract | ||
event StakeWithdrawn( | ||
address indexed staked, | ||
address indexed by, | ||
uint256 indexed slot, | ||
uint256 amount | ||
); | ||
} |
10 changes: 10 additions & 0 deletions
10
packages/solidity/src/xyo-chain/AddressStaking/interface/IAddressStakingFunctions.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
// SPDX-License-Identifier: GPL-3.0 | ||
pragma solidity ^0.8.20; | ||
|
||
interface IAddressStakingFunctions { | ||
function addStake(address staked, uint256 amount) external returns (bool); | ||
|
||
function removeStake(uint256 slot) external returns (bool); | ||
|
||
function withdrawStake(uint256 slot) external returns (bool); | ||
} |
26 changes: 26 additions & 0 deletions
26
packages/solidity/src/xyo-chain/AddressStaking/interface/IAddressStakingProperties.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// SPDX-License-Identifier: GPL-3.0 | ||
pragma solidity ^0.8.20; | ||
|
||
interface IAddressStakingProperties { | ||
// ============ Static ============ | ||
function minWithdrawalBlocks() external view returns (uint256); | ||
|
||
// ============ Volatile [Overall] ============ | ||
function active() external view returns (uint256); | ||
|
||
function pending() external view returns (uint256); | ||
|
||
function withdrawn() external view returns (uint256); | ||
|
||
// ============ Volatile [By Staker] ============ | ||
function activeByStaker(address staker) external view returns (uint256); | ||
|
||
function pendingByStaker(address staker) external view returns (uint256); | ||
|
||
function withdrawnByStalker(address staker) external view returns (uint256); | ||
|
||
// ============ Volatile [By Address Staked] ============ | ||
function activeByAddressStaked( | ||
address staked | ||
) external view returns (uint256); | ||
} |
Oops, something went wrong.