-
-
Notifications
You must be signed in to change notification settings - Fork 21
Honey DRIP #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Honey DRIP #6
Conversation
Requires threading the router address through the infra. Existing tests pass. New tests don't exist yet.
fix up path to use the token, not the pool actually approve the router for our contract
Avoid shavings of token B piling up
willjgriff
left a comment
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 start!
| await deployer.deploy(UniswapRouterMock); | ||
|
|
||
| await deployer.deploy(UnipoolMock, uniswapToken.address, HoneyTokenMock.address, UniswapRouterMock.address); | ||
| await deployer.deploy(UnipoolForeignPairMock, uniswapToken2.address, HoneyTokenMock.address, UniswapRouterMock.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.
Deployments to Rinkeby can actually use the Rinkeby deployment of Uniswap, instead of mocks. See if you can use that 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.
I probably can, and if I'd started out planning to do it that way it makes a lot of sense, but the tests are built assuming we can do things like mint arbitrary amounts of the pool tokens. And we'd still need the mocks for the local tests anyway.
If you think it's super important I can grind it out and rewrite the tests, but I'm not sure it's worth it at this stage.
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 unit tests aren't run on Rinkeby. Rinkeby deployment's are only for QA testing and we shouldn't use mocks on Rinkeby if we can avoid it, which I think we can here.
(mostly missed naming issues)
willjgriff
left a comment
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.
Looking good!
You seem to have missed some of the comments from my previous review though which are still "unresolved", please check and do them.
When I run the tests some of them fail. I run with npm run test.
Some of the import statement comments in the first test file can be considered for all of the test files, please check and update the other test files where required.
| } else if (pair.token1() == rewardToken) { | ||
| return pair.token0(); | ||
| } else { | ||
| // We can only reinvest if we're giving rewards in one side of the pair (currently) |
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 wouldn't imply future development, we have no idea what we will and won't do so remove the "(currently)".
| const UnipoolForeignPairMock = artifacts.require('./UnipoolMock.sol'); | ||
| const HoneyTokenMock = artifacts.require('./HoneyTokenMock.sol'); | ||
| const UniswapTokenMock = artifacts.require('./UniswapTokenMock.sol'); | ||
| const HONEY_TOKEN_XDAI_ADDRESS = '0x71850b7E9Ee3f13Ab46d67167341E4bDc905Eef9'; |
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 should be separate from the artifacts.require imports. Put it at a line below them.
|
|
||
| const UniswapToken = artifacts.require('UniswapTokenMock'); | ||
| const UniswapPair = artifacts.require('UniswapPairMock'); | ||
| const OtherToken = artifacts.require('UniswapTokenMock'); |
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 const is of type "UniswapToken" not "OtherToken". OtherToken is an instance of UniswapToken. Rename this to "UniswapToken"
| const UniswapToken = artifacts.require('UniswapTokenMock'); | ||
| const UniswapPair = artifacts.require('UniswapPairMock'); | ||
| const OtherToken = artifacts.require('UniswapTokenMock'); | ||
| const TradedToken = artifacts.require('HoneyTokenMock'); |
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.
Rename "HoneyTokenMock" to "TokenMock" and rename this const to "Token". Then the "OtherToken" above can be removed and where it's created below it can use this new "Token" object.
| this.unipool = await Unipool.new(this.uniswapToken.address, this.tradedToken.address); | ||
| this.otherToken = await OtherToken.new(); | ||
| this.rewardToken = await TradedToken.new(wallet1); | ||
| this.uniswapToken = await UniswapPair.new(this.rewardToken.address, this.otherToken.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.
Call this "uniswapPair" as it's of type UniswapPair.
|
|
||
| await this.unipool.reinvestReward({ from: wallet1 }); | ||
|
|
||
| expect(await this.unipool.earned(wallet1)).to.be.bignumber.almostEqualDiv1e18(web3.utils.toWei('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.
Shouldn't need to convert the 0 to wei here, just use 0.
|
|
||
| await deployer.deploy(HoneyTokenMock, senderAccount); | ||
| await deployer.deploy(OtherTokenMock); | ||
| await deployer.deploy(UniswapPairMock, HoneyTokenMock.address, OtherTokenMock.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.
This can be
const uniswapToken = await deployer.deploy(UniswapPairMock, HoneyTokenMock.address, OtherTokenMock.address);
Although I'd rename it to uniswapPair if that's what the contract is called. Then you can remove the below. Do elsewhere if possible too.
| await deployer.deploy(UniswapRouterMock); | ||
|
|
||
| await deployer.deploy(UnipoolMock, uniswapToken.address, HoneyTokenMock.address, UniswapRouterMock.address); | ||
| await deployer.deploy(UnipoolForeignPairMock, uniswapToken2.address, HoneyTokenMock.address, UniswapRouterMock.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.
The unit tests aren't run on Rinkeby. Rinkeby deployment's are only for QA testing and we shouldn't use mocks on Rinkeby if we can avoid it, which I think we can here.
|
|
||
| await this.unipool.reinvestReward({ from: wallet1 }); | ||
|
|
||
| expect(await this.unipool.balanceOf(wallet1)).to.be.bignumber.almostEqualDiv1e18(web3.utils.toWei('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.
I would copy this expect statement and put it before the reinvestReward call to check the balance is 1 before.
| uint256 acceptablePrice = immediatePrice.mul(10000 - MAX_SLIPPAGE_BASIS_POINTS).div(10000); | ||
| // Preflight here mostly for the benefit of unit tests | ||
| require(uniswapRouter.getAmountOut(tradeSize, rewardReserve, foreignReserve) >= acceptablePrice, | ||
| "Slippage too high for automagic reinvestment"); |
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 think we're wizards... I think you can remove the term "automagic" altogether.
This implements a Honeycomb DRIP (Dividend Reinvestment Program) in our Unipool fork, as described in https://forum.1hive.org/t/proposal-make-honey-sticky-automatic-dividend-reinvestment-vault/916 , just in time for the new farming proposal.
It uses essentially the same mechanism as the original external contract did, and just piggybacks on the existing earnings tracking to keep track of the dust.