Merge pull request #527 from harmony-one/rj_branch
Add StakeLockContract with basic locking/unlocking based on epochpull/531/head
commit
cc7621765e
@ -0,0 +1,4 @@ |
|||||||
|
The smart contract files in this folder contains protocol-level smart contracts that are critical to the overall operation of Harmony protocol: |
||||||
|
|
||||||
|
* Faucet.sol is the smart contract to dispense free test tokens in our testnet. |
||||||
|
* StakeLockContract.sol is the staking smart contract that receives and locks stakes. The stakes are used for the POS and sharding protocol. |
@ -0,0 +1,109 @@ |
|||||||
|
pragma solidity >=0.4.22; |
||||||
|
|
||||||
|
contract StakeLockContract { |
||||||
|
/** |
||||||
|
* @dev Error messages for require statements |
||||||
|
*/ |
||||||
|
string internal constant ALREADY_LOCKED = 'Tokens already locked'; |
||||||
|
string internal constant NOT_LOCKED = 'No tokens locked'; |
||||||
|
string internal constant AMOUNT_ZERO = 'Amount can not be 0'; |
||||||
|
|
||||||
|
uint256 internal constant LOCK_PERIOD_IN_EPOCHS = 3; // Final locking period TBD. |
||||||
|
|
||||||
|
uint256 internal numBlocksPerEpoch = 5; // This value is for testing only |
||||||
|
|
||||||
|
/** |
||||||
|
* @dev locked token structure |
||||||
|
*/ |
||||||
|
struct lockedToken { |
||||||
|
uint256 _amount; |
||||||
|
uint256 _blockNum; |
||||||
|
uint256 _epochNum; |
||||||
|
uint256 _continueCount; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @dev Holds number & validity of tokens locked for a given reason for |
||||||
|
* a specified address |
||||||
|
*/ |
||||||
|
mapping(address => lockedToken) private locked; |
||||||
|
mapping(address => uint) private indices; |
||||||
|
address[] private accountList; |
||||||
|
|
||||||
|
event Locked(address indexed _of, uint _amount, uint256 _epoch); |
||||||
|
event Unlocked(address indexed account, uint index); |
||||||
|
|
||||||
|
/** |
||||||
|
* @dev Returns total tokens held by an address (locked + transferable) |
||||||
|
* @param _of The address to query the total balance of |
||||||
|
*/ |
||||||
|
function lockedBalanceOf(address _of) |
||||||
|
public |
||||||
|
view |
||||||
|
returns (uint256 amount) |
||||||
|
{ |
||||||
|
amount = locked[_of]._amount; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @dev Locks a specified amount of tokens against an address |
||||||
|
* starting at the specific epoch |
||||||
|
* @param _epoch The epoch where the lock happens |
||||||
|
*/ |
||||||
|
function lock(uint256 _epoch) |
||||||
|
public |
||||||
|
payable |
||||||
|
returns (bool) |
||||||
|
{ |
||||||
|
// If tokens are already locked, then functions extendLock or |
||||||
|
// increaseLockAmount should be used to make any changes |
||||||
|
require(lockedBalanceOf(msg.sender) == 0, ALREADY_LOCKED); |
||||||
|
require(msg.value != 0, AMOUNT_ZERO); |
||||||
|
|
||||||
|
locked[msg.sender] = lockedToken(msg.value, block.number, currentEpoch(), 1); |
||||||
|
|
||||||
|
emit Locked(msg.sender, msg.value, _epoch); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @dev Unlocks the unlockable tokens of a specified address |
||||||
|
* @param _requestor Address of user, claiming back unlockable tokens |
||||||
|
*/ |
||||||
|
function unlock(address payable _requestor) |
||||||
|
public |
||||||
|
returns (uint256 unlockableTokens) |
||||||
|
{ |
||||||
|
unlockableTokens = getUnlockableTokens(_requestor); |
||||||
|
|
||||||
|
if (unlockableTokens != 0) { |
||||||
|
_requestor.transfer(unlockableTokens); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @dev Gets the unlockable tokens of a specified address |
||||||
|
* @param _of The address to query the the unlockable token count of |
||||||
|
*/ |
||||||
|
function getUnlockableTokens(address _of) |
||||||
|
public |
||||||
|
view |
||||||
|
returns (uint256 unlockableTokens) |
||||||
|
{ |
||||||
|
uint256 currentEpoch = currentEpoch(); |
||||||
|
if (locked[_of]._epochNum + locked[_of]._continueCount * LOCK_PERIOD_IN_EPOCHS < currentEpoch) { |
||||||
|
unlockableTokens = locked[_of]._amount; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @dev Gets the epoch number of the specified block number. |
||||||
|
*/ |
||||||
|
function currentEpoch() |
||||||
|
public |
||||||
|
view |
||||||
|
returns (uint256) |
||||||
|
{ |
||||||
|
return block.number / numBlocksPerEpoch; |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue