-
Notifications
You must be signed in to change notification settings - Fork 460
Consolidate staking pool mixins #2190
Conversation
185d85e
to
a838a58
Compare
a838a58
to
8d91614
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! Left a few comments and nits.
One thing to note is that I feel like with this change we need to be extra careful about communicating the fact that pools are intended only for makers controlled by a single entity, otherwise an operator might accidentally add an external maker who subsequently decreases the operator share to 0
senderAddress, | ||
operator, | ||
makerAddress | ||
operator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
idk if it still makes sense to use the operator address as a parameter for this error anymore –– maybe just the poolId instead? since you can get the operator from the poolId if you want
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like that change!
} | ||
|
||
if (membersReward > 0) { | ||
// Increment the balance of the pool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: update these comments too
contracts/staking/test/codesize.ts
Outdated
import * as chai from 'chai'; | ||
|
||
chaiSetup.configure(); | ||
const expect = chai.expect; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: import expect
from test-utils instead
contracts/staking/test/pools_test.ts
Outdated
accounts = await env.getAccountAddressesAsync(); | ||
owner = accounts[0]; | ||
users = accounts.slice(1); | ||
users = accounts.slice(2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: [owner, ...users] = accounts;
or even [owner, operator, ...users] = accounts;
const ethBalance = await this._web3Wrapper.getBalanceInWeiAsync(address); | ||
const wethBalance = await this.wethContract.balanceOf.callAsync(address); | ||
return BigNumber.sum(ethBalance, wethBalance); | ||
getAvailableRewardsBalanceAsync: async (): Promise<BigNumber> => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😎
import { PoolOperatorActor } from './pool_operator_actor'; | ||
|
||
export class MakerActor extends BaseActor { | ||
export class MakerActor extends PoolOperatorActor { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like the inheritance should go the other way around here, since (1) technically there's nothing stopping an operator from joining a staking pool, and (2) createStakingPool
is kinda what differentiates a pool operator from a vanilla maker
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's nothing stopping a maker from creating a pool either, right? Maybe We should just combine these into one actor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess my thought was that a maker "becomes" an operator by creating a pool (though I suppose the same can be said about an operator joining a pool). I think it's helpful to keep them as separate actors regardless, for clarity in e.g. rewards_test
if nothing else; open to other opinions tho
new StakingRevertErrors.OnlyCallableByPoolOperatorOrMakerError(makerAddress, operatorAddress), | ||
); | ||
}); | ||
it('should fail to add a maker to a pool if not called by operator/registered maker', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test does the same thing as 'Should fail to add a maker when called by someone other than the pool operator'
, so we can delete the latter
LibRichErrors.rrevert(LibStakingRichErrors.MakerPoolAssignmentError( | ||
LibStakingRichErrors.MakerPoolAssignmentErrorCodes.MakerAddressAlreadyRegistered, | ||
makerAddress, | ||
getStakingPoolIdOfMaker(makerAddress) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
getStakingPoolIdOfMaker(makerAddress) | |
poolJoinStatus.poolId |
LibRichErrors.rrevert(LibStakingRichErrors.MakerPoolAssignmentError( | ||
LibStakingRichErrors.MakerPoolAssignmentErrorCodes.MakerAddressAlreadyRegistered, | ||
makerAddress, | ||
getStakingPoolIdOfMaker(makerAddress) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
496dffb
to
01c7211
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is def much nicer to have these in one mixin.
Just some small suggestions but otherwise looks peachy keen!
/// @param newOperatorShare The newly decreased percentage of any rewards owned by the operator. | ||
function decreaseStakingPoolOperatorShare(bytes32 poolId, uint32 newOperatorShare) | ||
external | ||
onlyStakingPoolOperatorOrMaker(poolId) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😇
poolId: NIL_POOL_ID, | ||
confirmed: false | ||
}); | ||
poolJoinedByMakerAddress[makerAddress] = poolJoinStatus; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couldn't we just replace all the above with delete poolJoinedByMakerAddress[makerAddress]
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch!
/// @param makerAddress Address of maker | ||
/// @return Pool id, nil if maker is not yet assigned to a pool. | ||
function getStakingPoolIdOfMaker(address makerAddress) | ||
public |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this just be internal/private
since poolJoinedByMakerAddress
is a public variable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should have public getters for state variables that store a struct in a single word (the autogenerated getters don't play nicely with AbiV2). I'll actually make poolJoinedByMakerAddress
internal.
contracts/staking/test/pools_test.ts
Outdated
// maker removes themselves from pool | ||
await maker.removeMakerFromStakingPoolAsync(poolId, makerAddress); | ||
}); | ||
it('should successful remove another maker from a pool', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it('should successful remove another maker from a pool', async () => { | |
it('operator can remove a maker from their pool', async () => { |
contracts/staking/test/pools_test.ts
Outdated
await maker.joinStakingPoolAsMakerAsync(poolId); | ||
// operator adds maker to pool | ||
await poolOperator.addMakerToStakingPoolAsync(poolId, makerAddress); | ||
// maker removes themselves from pool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// maker removes themselves from pool | |
// operator removes maker from pool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 Maker/PoolOperatorActor inheritance thing is optional, should be a straightforward to change down the line should we decide to
…orPoolRewards public
454c0ff
to
7f51822
Compare
Description
This PR:
MixinStakingPoolMakers
,MixinStakingPoolModifiers
, andMixinStakingPool
into a single mixin. These contracts had a lot of overlap. The resulting contract is larger than I would like, but I think less confusing overall.onlyStakingPoolOperatorOrMaker
. Registered makers now essentially have the same rights as an operator. This includes admitting new makers into the pool, removing makers from the pool, or decreasing the operator's share. I like how this new behavior incentivizes operators to only allow makers that they control into a pool.StakingPoolRewardVault
andEthVault
#2186Testing instructions
Types of changes
Checklist:
[WIP]
if necessary.