Skip to content

Commit

Permalink
Merge pull request #15 from transmute-industries/feat/ENG-382-unbond-…
Browse files Browse the repository at this point in the history
…function

Feat/eng 382 unbond function
  • Loading branch information
gjgd committed Jul 19, 2018
2 parents 9340010 + 38a5ee8 commit 67d9ed9
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 27 deletions.
1 change: 0 additions & 1 deletion contracts/ProviderPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ contract ProviderPool is Ownable {
return providerPool.contains(_provider);
}

// TODO: Add default value in the main constructor
function setMaxNumberOfProviders(uint _maxNumber) external onlyOwner {
providerPool.setMaxSize(_maxNumber);
}
Expand Down
18 changes: 14 additions & 4 deletions contracts/RoundManager.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
pragma solidity ^0.4.24;

import "zeppelin-solidity/contracts/math/SafeMath.sol";
import "zeppelin-solidity/contracts/ownership/Ownable.sol";

contract RoundManager {
contract RoundManager is Ownable {
using SafeMath for uint;

// Round number of the last round
Expand All @@ -12,15 +13,24 @@ contract RoundManager {

uint public electionPeriodLength;
uint public rateLockDeadline;
// The time (in number of blocks) that a Delegator has to wait before he can withdraw() his tokens
uint public unbondingPeriod;

modifier onlyBeforeActiveRoundIsLocked() {
require(block.number.sub(startOfCurrentRound) < electionPeriodLength.sub(rateLockDeadline));
_;
}

constructor() public {
electionPeriodLength = 20;
rateLockDeadline = 5;
function setElectionPeriodLength(uint _electionPeriodLength) public onlyOwner {
electionPeriodLength = _electionPeriodLength;
}

function setRateLockDeadline(uint _rateLockDeadline) public onlyOwner {
rateLockDeadline = _rateLockDeadline;
}

function setUnbondingPeriod(uint _unbondingPeriod) public onlyOwner {
unbondingPeriod = _unbondingPeriod;
}

function initializeRound() external {
Expand Down
62 changes: 62 additions & 0 deletions contracts/TransmuteDPOS.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@ import "./ProviderPool.sol";

contract TransmuteDPOS is TransmuteToken, RoundManager, ProviderPool {

event DelegatorBonded(
address indexed _delegator,
address indexed _provider,
uint _amount
);

event DelegatorUnbonded(
address indexed _delegator,
address indexed _provider,
uint _amount
);

event ProviderAdded (
address indexed _provider,
uint _pricePerStorageMineral,
Expand All @@ -26,8 +38,11 @@ contract TransmuteDPOS is TransmuteToken, RoundManager, ProviderPool {
address indexed _provider
);

enum DelegatorStatus { Unbonded, UnbondedWithTokensToWithdraw, Bonded }

struct Delegator {
address delegateAddress;
// TODO: rename variable
uint amountBonded;
}

Expand All @@ -48,6 +63,16 @@ contract TransmuteDPOS is TransmuteToken, RoundManager, ProviderPool {
uint public numberOfProviders;
mapping(address => Provider) public providers;

mapping (address => uint) public withdrawBlocks;

// FIXME: Those are temporary values
constructor() public {
// Set constants from RoundManager
electionPeriodLength = 20;
rateLockDeadline = 5;
unbondingPeriod = 10;
}

function provider(uint _pricePerStorageMineral, uint _pricePerComputeMineral, uint _blockRewardCut, uint _feeShare)
external onlyBeforeActiveRoundIsLocked
{
Expand Down Expand Up @@ -92,5 +117,42 @@ contract TransmuteDPOS is TransmuteToken, RoundManager, ProviderPool {
if (p.status == ProviderStatus.Registered) {
updateProvider(_provider, p.totalAmountBonded);
}
emit DelegatorBonded(msg.sender, _provider, _amount);
}

function unbond() external {
// Only Bonded Delegators can call the function
require(delegatorStatus(msg.sender) == DelegatorStatus.Bonded);
// TODO: What if a Provider calls unbond() on himself ?
// Should he resign ?
// What about the tokens of the Delegators that bonded to him ?
// For now we prevent providers from calling this function
require(providers[msg.sender].status == ProviderStatus.Unregistered);

Delegator storage d = delegators[msg.sender];
Provider storage p = providers[d.delegateAddress];
// Sets the block number from which the Delegator will be able to withdraw() his tokens
withdrawBlocks[msg.sender] = block.number.add(unbondingPeriod);
// Decrease the totalAmountBonded parameter of the provider
p.totalAmountBonded = p.totalAmountBonded.sub(d.amountBonded);
updateProvider(d.delegateAddress, p.totalAmountBonded);
emit DelegatorUnbonded(msg.sender, d.delegateAddress, d.amountBonded);
// Remove delegator from the list. He is no longer in the the Bonded State
delete delegators[msg.sender];
}

// TODO: Create the same function for Providers
// This will remove the need for ProviderStatus inside the Provider Struct
function delegatorStatus(address _delegator) public view returns (DelegatorStatus) {
if (delegators[_delegator].amountBonded != 0) {
// If _delegator is in the mapping, he is Bonded
return DelegatorStatus.Bonded;
} else if (withdrawBlocks[_delegator] != 0) {
// Else if _delegator has a withdrawBlock, he just called unbond() and didn't withdraw() yet
return DelegatorStatus.UnbondedWithTokensToWithdraw;
} else {
// Else he is Unbonded: either he didn't call bond() or he called bond() unbond() and withdraw()
return DelegatorStatus.Unbonded;
}
}
}
9 changes: 7 additions & 2 deletions test/TestRoundManager.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@ const { blockMiner, assertFail } = require('./utils.js');

contract('RoundManager', accounts => {

let rm, electionPeriodLength;
let rm;
const electionPeriodLength = 20;
const rateLockDeadline = 5;
const unbondingPeriod = 10;

describe('initializeRound', () => {

before(async () => {
rm = await RoundManager.deployed();
electionPeriodLength = await rm.electionPeriodLength.call();
await rm.setElectionPeriodLength(electionPeriodLength);
await rm.setRateLockDeadline(rateLockDeadline);
await rm.setUnbondingPeriod(unbondingPeriod);
await blockMiner.mineUntilEndOfElectionPeriod(rm);
assert.equal(0, (web3.eth.blockNumber + 1) % electionPeriodLength);
});
Expand Down
Loading

0 comments on commit 67d9ed9

Please sign in to comment.