-
Notifications
You must be signed in to change notification settings - Fork 59
[WIP] Brian/auction set up logic #181
Conversation
d8c4754
to
97cbbe0
Compare
Pull Request Test Coverage Report for Build 1535
💛 - Coveralls |
uint256[] memory currentSetUnits = currentSetInterface.getUnits(); | ||
uint256[] memory rebalancingSetUnits = rebalancingSetInterface.getUnits(); | ||
|
||
for (uint16 i=0; i < combinedTokenArray.length; i++) { |
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.
Let's use uint256
vs uint16 - since there are no gas savings
* @param _unit The units of the component token | ||
* @param _naturalUnit The natural unit of the Set token | ||
*/ | ||
function computeUnits( |
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.
Do we have one of these functions elsewhere? If so, maybe we can avoid duplication by using a lib
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 have something similar in Core but don't see a need to have us make a call to it in order to calculate this.
const RebalancingSetToken = artifacts.require('RebalancingSetToken'); | ||
const Core = artifacts.require('CoreMock'); | ||
|
||
// import { injectInTruffle } from 'sol-trace-set'; |
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.
Remove if not needed?
ChaiSetup.configure(); | ||
const { expect } = chai; | ||
const RebalancingSetToken = artifacts.require('RebalancingSetToken'); | ||
const Core = artifacts.require('CoreMock'); |
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.
Make naming consistent? Core
and CoreMock
. Maybe go with CoreMock
so that future we don't trip over this.
let rebalancingSetToken: RebalancingSetTokenContract; | ||
let components: StandardTokenMockContract[] = []; | ||
|
||
let core: CoreMockContract; |
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.
wonder if we should rename this all to coreMock
to be clear
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 don't see a reason to. We're only using CoreMock in this test suite...but it's still what we're using as Core.
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.
+1, let's use coreMock here when it's coreMock
|
||
before(async () => { | ||
await blockchain.saveSnapshotAsync(); | ||
ABIDecoder.addABI(Core.abi); |
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.
CoreMock
?
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.
si
blockchain.increaseTimeAsync(timeFastForward); | ||
await rebalancingSetToken.propose.sendTransactionAsync( | ||
newRebalancingToken, | ||
await blockchain.increaseTimeAsync(timeFastForward); |
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.
😢
}); | ||
|
||
describe('#mint called from Core', async () => { | ||
let rebalancingToken: RebalancingSetTokenContract; |
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.
As we discussed - a lot of this setup could be moved into a wrapper.
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.
Yep another PR methinks
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.
Yes and no, a lot of this stuff is unnecessary such as declaring a new rebalancingToken
and setName, setSymbol
(defined in coreWrapper already) that I noticed. I cleaned this up in my PR that should be on master. Makes following along with specs easier
@asoong Could you help do a review as well? |
…code to redeem currentSets when rebalance called. Waiting on RebalancingTokenFactory to complete tests.
…nt256 on rebalancing set token.
computeUnits(currentSetUnits[indexCurrent], currentSetNaturalUnit) | ||
); | ||
} else { | ||
combinedCurrentUnits.push(uint256(0)); |
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.
interesting, do you have to cast this here? uint256(0)
?
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.
Prob not but feel like we've fallen on the standard of explicitly stating what all the uints are
let subjectCaller: Address; | ||
|
||
let newRebalancingToken: Address; | ||
let currentSetToken: SetTokenContract; |
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.
e.g. this is not being referenced elsewhere in this spec, don't need to define a variable
let newRebalancingToken: Address; | ||
let currentSetToken: SetTokenContract; | ||
|
||
const naturalUnit: BigNumber = ether(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.
same
}); | ||
|
||
describe('#mint', async () => { | ||
describe('#mint called directly', 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.
The whole point of these specs is to make sure the require(msg.sender == ISetFactory(factory).core());
triggers correct? I say keep this section short and move the other test cases into #mint called from Core
to be clear. Right now you have:
#mint called directly:
- it updates the balances of the user correctly
- it updates the totalSupply_ correctly
- it emits a Transfer log denoting a minting
- when the caller is not Core
#mint called from Core
- it updates the balances of the user correctly
- when mint is called from Rebalance state
..?
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.
New:
#mint called directly:
when the caller is not Core
#mint called from Core
it updates the balances of the user correctly
it updates the totalSupply_ correctly
it emits a Transfer log denoting a minting
when mint is called from Rebalance state
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.
Agree mostly do you think it makes sense to keep one "happy" path case in the "direct" case so that we aren't accidentally missing something there?
let subjectQuantity: BigNumber; | ||
let subjectCaller: Address; | ||
|
||
let currentSetToken: SetTokenContract; |
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.
Remove anything not referenced later in this test case
let currentSetToken: SetTokenContract; | ||
let newRebalancingSetToken: SetTokenContract; | ||
|
||
const naturalUnit: BigNumber = ether(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.
same
const manager = managerAccount; | ||
const initialSet = currentSetToken.address; | ||
const initialUnitShares = new BigNumber(1); | ||
const rebalanceInterval = new BigNumber(90000); |
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.
Ideally a constant for these numbers
it('creates the correct combinedCurrentUnits', async () => { | ||
await subject(); | ||
|
||
const expectedCombinedCurrentUnits = [ether(2), ether(2), ether(0)]; |
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.
where do these come from?
const timeFastForward = 100000; | ||
|
||
blockchain.increaseTimeAsync(timeFastForward); | ||
await blockchain.increaseTimeAsync(timeFastForward); |
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.
Would really love for this whole beforeEach to be one wrapper function that encompasses all the state transitions
components = await erc20Wrapper.deployTokensAsync(3, deployerAccount); | ||
await erc20Wrapper.approveTransfersAsync(components, transferProxy.address); | ||
|
||
const currentComponentAddresses = _.map(components.slice(0, 2), token => token.address); |
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.
Define a constant for this slice
naturalUnit, | ||
); | ||
|
||
const newComponentAddresses = _.map(components.slice(1, 3), token => token.address); |
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
factory = await coreWrapper.deploySetTokenFactoryAsync(coreAccount); | ||
await erc20Wrapper.approveTransfersAsync(components, transferProxy.address); | ||
|
||
const currentComponentAddresses = _.map(components.slice(0, 2), token => token.address); |
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.
Why do you need to slice here?
Doing some cleanup now will help you in the next phase. @felix2feng In the future, let's keep the PR smaller. Maybe start with |
6b1f608
to
0f73195
Compare
…erate expected arrays during propose.
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 is a SIGNIFICANT improvement. I'm deferring to @asoong for thumbs up
utils/RebalancingTokenWrapper.ts
Outdated
this._blockchain = blockchain; | ||
} | ||
|
||
public async createSetTokens( |
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 doesn't seem rebalancing specific. Should this be in CoreWrapper instead?
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.
If we wanna move it at some point we can. Just feels like the only functionality we need multiple SetTokens for rn is rebalancing.
utils/RebalancingTokenWrapper.ts
Outdated
); | ||
} | ||
|
||
public async constructCombinedUnitArray( |
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.
Could we add a javadoc on what this does?
let newRebalancingSetToken: SetTokenContract; | ||
|
||
beforeEach(async () => { | ||
const setTokens = await rebalancingTokenWrapper.createSetTokens(coreMock, factory.address, transferProxy.address); |
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.
You could combine this and the next two lines in one line
const [ currentSetToken, newRebalancingSetToken ] = await rebalancingTokenWrapper.createSetTokens...
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.
Different scoping on them though
proposalPeriod | ||
); | ||
|
||
|
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.
extra new line
factory = await coreWrapper.deploySetTokenFactoryAsync(coreAccount); | ||
await erc20Wrapper.approveTransfersAsync(components, transferProxy.address); | ||
|
||
const currentComponentAddresses = _.map(components, token => token.address); |
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.
Could we put the map function in a util or something? It's a bit jarring to see this low level stuff in a test
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.
Those tests are gonna be deleted anyway but I also don't think it's worthwhile to create a full other util for one line of code.
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.
Sorry not gonna be deleted was looking at wrong test suite but still don't think its worth creating its own util... _.map is the util.
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.
LGTM. I left comments on some more improvements you can address as part of this or the next PR. Also consider moving propose and bid specs into its own file
utils/RebalancingTokenWrapper.ts
Outdated
); | ||
} | ||
|
||
public async defaultTransitionToPropose( |
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.
Why are these prefixed to default?
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.
default -> propose state
utils/RebalancingTokenWrapper.ts
Outdated
this._blockchain = blockchain; | ||
} | ||
|
||
public async createSetTokens( |
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.
suffix methods Async
utils/RebalancingTokenWrapper.ts
Outdated
const components = await this._erc20Wrapper.deployTokensAsync(3, this._tokenOwnerAddress); | ||
await this._erc20Wrapper.approveTransfersAsync(components, transferProxy); | ||
|
||
const set1Components = components.slice(0, 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: don't use numbers. firstSetComponents
utils/constants.ts
Outdated
export const ZRX_TOKEN_ADDRESS = '0x871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c'; | ||
|
||
// Rebalancing Constants | ||
export const DEFAULT_PERIOD_INTERVAL = new BigNumber(90000); |
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.
Helps to be even more realistic here for clarity. Your contracts specify day cutoffs. Create constants for maybe ONE_DAY_IN_SECONDS
and your test case for invalid PERIOD_INTERVAL
can be ONE_DAY_IN_SECONDS.sub(1)
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 makes your usage more readable: const proposalPeriod = ONE_DAY_IN_SECONDS;
vs.
const proposalPeriod = DEFAULT_PERIOD_INTERVAL;
No description provided.