Skip to content

Commit

Permalink
Fix SushiMaker and add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
chefnomi committed Aug 26, 2020
1 parent f9b98fe commit 88a141d
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 2 deletions.
14 changes: 12 additions & 2 deletions contracts/SushiMaker.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,16 @@ contract SushiMaker {
}

function _toWETH(address token) internal returns (uint256) {
if (token == sushi || token == weth) return 0; // No action needed
if (token == sushi) {
uint amount = IERC20(token).balanceOf(address(this));
IERC20(token).transfer(bar, amount);
return 0;
}
if (token == weth) {
uint amount = IERC20(token).balanceOf(address(this));
IERC20(token).transfer(factory.getPair(weth, sushi), amount);
return amount;
}
IUniswapV2Pair pair = IUniswapV2Pair(factory.getPair(token, weth));
(uint reserve0, uint reserve1,) = pair.getReserves();
address token0 = pair.token0();
Expand All @@ -45,6 +54,7 @@ contract SushiMaker {
uint denominator = reserveIn.mul(1000).add(amountInWithFee);
uint amountOut = numerator / denominator;
(uint amount0Out, uint amount1Out) = token0 == token ? (uint(0), amountOut) : (amountOut, uint(0));
IERC20(token).transfer(address(pair), amountIn);
pair.swap(amount0Out, amount1Out, factory.getPair(weth, sushi), new bytes(0));
return amountOut;
}
Expand All @@ -59,6 +69,6 @@ contract SushiMaker {
uint denominator = reserveIn.mul(1000).add(amountInWithFee);
uint amountOut = numerator / denominator;
(uint amount0Out, uint amount1Out) = token0 == weth ? (uint(0), amountOut) : (amountOut, uint(0));
pair.swap(amount0Out, amount1Out, factory.getPair(weth, sushi), new bytes(0));
pair.swap(amount0Out, amount1Out, bar, new bytes(0));
}
}
61 changes: 61 additions & 0 deletions test/SushiMaker.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
const SushiToken = artifacts.require('SushiToken');
const SushiMaker = artifacts.require('SushiMaker');
const MockERC20 = artifacts.require('MockERC20');
const UniswapV2Pair = artifacts.require('UniswapV2Pair');
const UniswapV2Factory = artifacts.require('UniswapV2Factory');

contract('SushiMaker', ([alice, bar, minter]) => {
beforeEach(async () => {
this.factory = await UniswapV2Factory.new(alice, { from: alice });
this.sushi = await SushiToken.new({ from: alice });
await this.sushi.mint(minter, '100000000', { from: alice });
this.weth = await MockERC20.new('WETH', 'WETH', '100000000', { from: minter });
this.token1 = await MockERC20.new('TOKEN1', 'TOKEN', '100000000', { from: minter });
this.token2 = await MockERC20.new('TOKEN2', 'TOKEN2', '100000000', { from: minter });
this.maker = await SushiMaker.new(this.factory.address, bar, this.sushi.address, this.weth.address);
this.sushiWETH = await UniswapV2Pair.at((await this.factory.createPair(this.weth.address, this.sushi.address)).logs[0].args.pair);
this.wethToken1 = await UniswapV2Pair.at((await this.factory.createPair(this.weth.address, this.token1.address)).logs[0].args.pair);
this.wethToken2 = await UniswapV2Pair.at((await this.factory.createPair(this.weth.address, this.token2.address)).logs[0].args.pair);
this.token1Token2 = await UniswapV2Pair.at((await this.factory.createPair(this.token1.address, this.token2.address)).logs[0].args.pair);
});

it('should make SUSHIs successfully', async () => {
await this.factory.setFeeTo(this.maker.address, { from: alice });
await this.weth.transfer(this.sushiWETH.address, '10000000', { from: minter });
await this.sushi.transfer(this.sushiWETH.address, '10000000', { from: minter });
await this.sushiWETH.mint(minter);
await this.weth.transfer(this.wethToken1.address, '10000000', { from: minter });
await this.token1.transfer(this.wethToken1.address, '10000000', { from: minter });
await this.wethToken1.mint(minter);
await this.weth.transfer(this.wethToken2.address, '10000000', { from: minter });
await this.token2.transfer(this.wethToken2.address, '10000000', { from: minter });
await this.wethToken2.mint(minter);
await this.token1.transfer(this.token1Token2.address, '10000000', { from: minter });
await this.token2.transfer(this.token1Token2.address, '10000000', { from: minter });
await this.token1Token2.mint(minter);
// Fake some revenue
await this.token1.transfer(this.token1Token2.address, '100000', { from: minter });
await this.token2.transfer(this.token1Token2.address, '100000', { from: minter });
await this.token1Token2.sync();
await this.token1.transfer(this.token1Token2.address, '10000000', { from: minter });
await this.token2.transfer(this.token1Token2.address, '10000000', { from: minter });
await this.token1Token2.mint(minter);
// Maker should have the LP now
assert.equal((await this.token1Token2.balanceOf(this.maker.address)).valueOf(), '16528');
// After calling convert, bar should have SUSHI value at ~1/6 of revenue
await this.maker.convert(this.token1.address, this.token2.address);
assert.equal((await this.sushi.balanceOf(bar)).valueOf(), '32965');
assert.equal((await this.token1Token2.balanceOf(this.maker.address)).valueOf(), '0');
// Should also work for SUSHI-ETH pair
await this.sushi.transfer(this.sushiWETH.address, '100000', { from: minter });
await this.weth.transfer(this.sushiWETH.address, '100000', { from: minter });
await this.sushiWETH.sync();
await this.sushi.transfer(this.sushiWETH.address, '10000000', { from: minter });
await this.weth.transfer(this.sushiWETH.address, '10000000', { from: minter });
await this.sushiWETH.mint(minter);
assert.equal((await this.sushiWETH.balanceOf(this.maker.address)).valueOf(), '16537');
await this.maker.convert(this.sushi.address, this.weth.address);
assert.equal((await this.sushi.balanceOf(bar)).valueOf(), '66249');
assert.equal((await this.sushiWETH.balanceOf(this.maker.address)).valueOf(), '0');
});
});

0 comments on commit 88a141d

Please sign in to comment.