Skip to content

Commit a313fa6

Browse files
authored
Merge pull request #136 from livepeer/yf/eth-payments
Use ETH for job deposits and fee payments
2 parents b5cd4f3 + ad4059c commit a313fa6

File tree

11 files changed

+217
-155
lines changed

11 files changed

+217
-155
lines changed

contracts/bonding/BondingManager.sol

Lines changed: 45 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ contract BondingManager is ManagerProxyTarget, IBondingManager {
4141
// Represents a delegator's current state
4242
struct Delegator {
4343
uint256 bondedAmount; // The amount of bonded tokens
44-
uint256 unbondedAmount; // The amount of unbonded tokens
44+
uint256 fees; // The amount of fees collected
4545
address delegateAddress; // The address delegated to
4646
uint256 delegatedAmount; // The amount of tokens delegated to the delegator
4747
uint256 startRound; // The round the delegator transitions to bonded phase and is delegated to someone
@@ -279,19 +279,8 @@ contract BondingManager is ManagerProxyTarget, IBondingManager {
279279
}
280280

281281
if (_amount > 0) {
282-
if (_amount > del.unbondedAmount) {
283-
// If amount to bond is greater than the delegator's unbonded amount
284-
// use the delegator's unbonded amount and transfer the rest from the sender
285-
uint256 transferAmount = _amount.sub(del.unbondedAmount);
286-
// Set unbonded amount to 0
287-
del.unbondedAmount = 0;
288-
// Transfer the token to the Minter
289-
livepeerToken().transferFrom(msg.sender, minter(), transferAmount);
290-
} else {
291-
// If the amount to bond is less than or equal to the delegator's unbonded amount
292-
// just use the delegator's unbonded amount
293-
del.unbondedAmount = del.unbondedAmount.sub(_amount);
294-
}
282+
// Transfer the LPT to the Minter
283+
livepeerToken().transferFrom(msg.sender, minter(), _amount);
295284
}
296285

297286
Bond(_to, msg.sender);
@@ -336,35 +325,46 @@ contract BondingManager is ManagerProxyTarget, IBondingManager {
336325
}
337326

338327
/**
339-
* @dev Withdraws withdrawable funds back to the caller after unbonding period.
328+
* @dev Withdraws bonded stake to the caller after unbonding period.
340329
*/
341-
function withdraw()
330+
function withdrawStake()
342331
external
343332
whenSystemNotPaused
344333
currentRoundInitialized
345334
autoClaimTokenPoolsShares
346335
{
347-
// Delegator must either have unbonded tokens or be in the unbonded state
348-
require(delegators[msg.sender].unbondedAmount > 0 || delegatorStatus(msg.sender) == DelegatorStatus.Unbonded);
336+
// Delegator must be in the unbonded state
337+
require(delegatorStatus(msg.sender) == DelegatorStatus.Unbonded);
349338

350-
uint256 amount = 0;
339+
uint256 amount = delegators[msg.sender].bondedAmount;
340+
delegators[msg.sender].bondedAmount = 0;
341+
delegators[msg.sender].withdrawRound = 0;
351342

352-
if (delegators[msg.sender].unbondedAmount > 0) {
353-
// Withdraw unbonded amount
354-
amount = amount.add(delegators[msg.sender].unbondedAmount);
355-
delegators[msg.sender].unbondedAmount = 0;
356-
}
343+
// Tell Minter to transfer stake (LPT) to the delegator
344+
minter().transferTokens(msg.sender, amount);
357345

358-
if (delegatorStatus(msg.sender) == DelegatorStatus.Unbonded) {
359-
// Withdraw bonded amount which is now unbonded
360-
amount = amount.add(delegators[msg.sender].bondedAmount);
361-
delegators[msg.sender].bondedAmount = 0;
362-
delegators[msg.sender].withdrawRound = 0;
363-
}
346+
WithdrawStake(msg.sender);
347+
}
364348

365-
minter().transferTokens(msg.sender, amount);
349+
/**
350+
* @dev Withdraws fees to the caller
351+
*/
352+
function withdrawFees()
353+
external
354+
whenSystemNotPaused
355+
currentRoundInitialized
356+
autoClaimTokenPoolsShares
357+
{
358+
// Delegator must have fees
359+
require(delegators[msg.sender].fees > 0);
360+
361+
uint256 amount = delegators[msg.sender].fees;
362+
delegators[msg.sender].fees = 0;
366363

367-
Withdraw(msg.sender);
364+
// Tell Minter to transfer fees (ETH) to the delegator
365+
minter().withdrawETH(msg.sender, amount);
366+
367+
WithdrawFees(msg.sender);
368368
}
369369

370370
/*
@@ -575,10 +575,10 @@ contract BondingManager is ManagerProxyTarget, IBondingManager {
575575
}
576576

577577
/*
578-
* @dev Returns bonded stake for a delegator. Includes reward pool shares since lastClaimTokenPoolsSharesRound
578+
* @dev Returns pending bonded stake for a delegator. Includes reward pool shares since lastClaimTokenPoolsSharesRound
579579
* @param _delegator Address of delegator
580580
*/
581-
function delegatorStake(address _delegator) public view returns (uint256) {
581+
function pendingStake(address _delegator) public view returns (uint256) {
582582
Delegator storage del = delegators[_delegator];
583583

584584
// Add rewards from the rounds during which the delegator was bonded to a transcoder
@@ -603,16 +603,16 @@ contract BondingManager is ManagerProxyTarget, IBondingManager {
603603
}
604604

605605
/*
606-
* @dev Returns unbonded amount for a delegator. Includes fee pool shares since lastClaimTokenPoolsSharesRound
606+
* @dev Returns pending fees for a delegator. Includes fee pool shares since lastClaimTokenPoolsSharesRound
607607
* @param _delegator Address of delegator
608608
*/
609-
function delegatorUnbondedAmount(address _delegator) public view returns (uint256) {
609+
function pendingFees(address _delegator) public view returns (uint256) {
610610
Delegator storage del = delegators[_delegator];
611611

612612
// Add fees from the rounds during which the delegator was bonded to a transcoder
613613
if (delegatorStatus(_delegator) == DelegatorStatus.Bonded && transcoderStatus(del.delegateAddress) == TranscoderStatus.Registered) {
614614
uint256 currentRound = roundsManager().currentRound();
615-
uint256 currentUnbondedAmount = del.unbondedAmount;
615+
uint256 currentFees = del.fees;
616616
uint256 currentBondedAmount = del.bondedAmount;
617617

618618
for (uint256 i = del.lastClaimTokenPoolsSharesRound + 1; i <= currentRound; i++) {
@@ -621,16 +621,16 @@ contract BondingManager is ManagerProxyTarget, IBondingManager {
621621
if (tokenPools.hasClaimableShares()) {
622622
bool isTranscoder = _delegator == del.delegateAddress;
623623
// Calculate and add fee pool share from this round
624-
currentUnbondedAmount = currentUnbondedAmount.add(tokenPools.feePoolShare(currentBondedAmount, isTranscoder));
624+
currentFees = currentFees.add(tokenPools.feePoolShare(currentBondedAmount, isTranscoder));
625625
// Calculate new bonded amount with rewards from this round. Updated bonded amount used
626626
// to calculate fee pool share in next round
627627
currentBondedAmount = currentBondedAmount.add(tokenPools.rewardPoolShare(currentBondedAmount, isTranscoder));
628628
}
629629
}
630630

631-
return currentUnbondedAmount;
631+
return currentFees;
632632
} else {
633-
return del.unbondedAmount;
633+
return del.fees;
634634
}
635635
}
636636

@@ -743,12 +743,12 @@ contract BondingManager is ManagerProxyTarget, IBondingManager {
743743
)
744744
public
745745
view
746-
returns (uint256 bondedAmount, uint256 unbondedAmount, address delegateAddress, uint256 delegatedAmount, uint256 startRound, uint256 withdrawRound, uint256 lastClaimTokenPoolsSharesRound)
746+
returns (uint256 bondedAmount, uint256 fees, address delegateAddress, uint256 delegatedAmount, uint256 startRound, uint256 withdrawRound, uint256 lastClaimTokenPoolsSharesRound)
747747
{
748748
Delegator storage del = delegators[_delegator];
749749

750750
bondedAmount = del.bondedAmount;
751-
unbondedAmount = del.unbondedAmount;
751+
fees = del.fees;
752752
delegateAddress = del.delegateAddress;
753753
delegatedAmount = del.delegatedAmount;
754754
startRound = del.startRound;
@@ -834,26 +834,25 @@ contract BondingManager is ManagerProxyTarget, IBondingManager {
834834

835835
if (del.lastClaimTokenPoolsSharesRound > 0) {
836836
uint256 currentBondedAmount = del.bondedAmount;
837-
uint256 currentUnbondedAmount = del.unbondedAmount;
837+
uint256 currentFees = del.fees;
838838

839839
for (uint256 i = del.lastClaimTokenPoolsSharesRound + 1; i <= _endRound; i++) {
840840
TokenPools.Data storage tokenPools = transcoders[del.delegateAddress].tokenPoolsPerRound[i];
841841

842-
843842
if (tokenPools.hasClaimableShares()) {
844843
bool isTranscoder = _delegator == del.delegateAddress;
845844

846845
var (fees, rewards) = tokenPools.claimShare(currentBondedAmount, isTranscoder);
847846

848-
currentUnbondedAmount = currentUnbondedAmount.add(fees);
847+
currentFees = currentFees.add(fees);
849848
currentBondedAmount = currentBondedAmount.add(rewards);
850849
}
851850
}
852851

853852
// Rewards are bonded by default
854853
del.bondedAmount = currentBondedAmount;
855854
// Fees are unbonded by default
856-
del.unbondedAmount = currentUnbondedAmount;
855+
del.fees = currentFees;
857856
}
858857

859858
del.lastClaimTokenPoolsSharesRound = _endRound;

contracts/bonding/IBondingManager.sol

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ contract IBondingManager {
1313
event Reward(address indexed transcoder, uint256 amount);
1414
event Bond(address indexed delegate, address indexed delegator);
1515
event Unbond(address indexed delegate, address indexed delegator);
16-
event Withdraw(address indexed delegator);
16+
event WithdrawStake(address indexed delegator);
17+
event WithdrawFees(address indexed delegator);
1718

1819
// External functions
1920
function setActiveTranscoders() external;

contracts/jobs/JobsManager.sol

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -233,15 +233,14 @@ contract JobsManager is ManagerProxyTarget, IVerifiable, IJobsManager {
233233
}
234234

235235
/*
236-
* @dev Deposit funds for jobs
237-
* @param _amount Amount to deposit
236+
* @dev Deposit ETH for jobs
238237
*/
239-
function deposit(uint256 _amount) external whenSystemNotPaused {
240-
broadcasters[msg.sender].deposit = broadcasters[msg.sender].deposit.add(_amount);
241-
// Transfer tokens for deposit to Minter. Sender needs to approve amount first
242-
livepeerToken().transferFrom(msg.sender, minter(), _amount);
238+
function deposit() external payable whenSystemNotPaused {
239+
broadcasters[msg.sender].deposit = broadcasters[msg.sender].deposit.add(msg.value);
240+
// Transfer ETH for deposit to Minter
241+
minter().depositETH.value(msg.value)();
243242

244-
Deposit(msg.sender, _amount);
243+
Deposit(msg.sender, msg.value);
245244
}
246245

247246
/*
@@ -253,7 +252,7 @@ contract JobsManager is ManagerProxyTarget, IVerifiable, IJobsManager {
253252

254253
uint256 amount = broadcasters[msg.sender].deposit;
255254
delete broadcasters[msg.sender];
256-
minter().transferTokens(msg.sender, amount);
255+
minter().withdrawETH(msg.sender, amount);
257256

258257
Withdraw(msg.sender);
259258
}

contracts/test/BondingManagerMock.sol

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,12 @@ contract BondingManagerMock is IBondingManager {
4040
withdrawAmount = _amount;
4141
}
4242

43-
function withdraw() external {
44-
minter.transferTokens(msg.sender, withdrawAmount);
43+
function withdraw(bool _unbonded, address _recipient) external {
44+
if (_unbonded) {
45+
minter.withdrawETH(_recipient, withdrawAmount);
46+
} else {
47+
minter.transferTokens(_recipient, withdrawAmount);
48+
}
4549
}
4650

4751
function reward() external {

contracts/test/JobsManagerMock.sol

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,16 @@ contract JobsManagerMock is IJobsManager {
9090
return bondingManager.slashTranscoder(transcoder, finder, slashAmount, finderFee);
9191
}
9292

93-
function withdraw() external {
94-
minter.transferTokens(msg.sender, withdrawAmount);
93+
function deposit() external payable {
94+
minter.depositETH.value(msg.value)();
95+
}
96+
97+
function withdraw(bool _unbonded, address _recipient) external {
98+
if (_unbonded) {
99+
minter.withdrawETH(_recipient, withdrawAmount);
100+
} else {
101+
minter.transferTokens(_recipient, withdrawAmount);
102+
}
95103
}
96104

97105
function callVerify() external payable {

contracts/test/MinterMock.sol

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ contract MinterMock is IMinter {
1818

1919
function burnTokens(uint256 _amount) external {}
2020

21+
function withdrawETH(address _to, uint256 _amount) external {}
22+
23+
function depositETH() external payable returns (bool) {
24+
return true;
25+
}
26+
2127
function addToRedistributionPool(uint256 _amount) external {}
2228

2329
function setCurrentRewardTokens() external {}

contracts/token/IMinter.sol

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,7 @@ contract IMinter {
88
function createReward(uint256 _fracNum, uint256 _fracDenom) external returns (uint256);
99
function transferTokens(address _to, uint256 _amount) external;
1010
function burnTokens(uint256 _amount) external;
11+
function depositETH() external payable returns (bool);
12+
function withdrawETH(address _to, uint256 _amount) external;
1113
function setCurrentRewardTokens() external;
1214
}

contracts/token/Minter.sol

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,22 @@ contract Minter is Manager, IMinter {
107107
livepeerToken().burn(_amount);
108108
}
109109

110+
/*
111+
* @dev Withdraw ETH to a recipient
112+
* @param _to Recipient address
113+
* @param _amount Amount of ETH
114+
*/
115+
function withdrawETH(address _to, uint256 _amount) external onlyBondingManagerOrJobsManager whenSystemNotPaused {
116+
_to.transfer(_amount);
117+
}
118+
119+
/*
120+
* @dev Deposit ETH from the JobsManager
121+
*/
122+
function depositETH() external payable onlyJobsManager whenSystemNotPaused returns (bool) {
123+
return true;
124+
}
125+
110126
/*
111127
* @dev Set the reward token amounts for the round. Only callable by the RoundsManager
112128
*/

0 commit comments

Comments
 (0)