protocol/contracts/zero-ex/test/features/liquidity_provider_test.ts
Lawrence Forman 164a5d44d9
bsc<->development rebase (#189)
* FQT: Pack Protocol/source name into source ID (#162)

* `@0x/contracts-zero-ex`: Encode protocol ID and source name in bridge source ID
`@0x/asset-swapper`: Use new bridge source ID encoding.

* fix linter issues

* contracts cleanup (#164)

* `@0x/contracts-zero-ex`: Add PancakeSwapFeature

* `@0x/contracts-zero-ex`: Remove tokenspender/allowance target/greedy tokens stuff.'
`@0x/contract-addresses`: Add BSC addresses. Remove exchangeProxyAllowanceTarget.
`@0x/migrations`: Remove exchangeProxyAllowanceTarget.

* Update contracts/zero-ex/contracts/src/features/IPancakeSwapFeature.sol

Co-authored-by: mzhu25 <mchl.zhu.96@gmail.com>

* `@0x/contracts-zero-ex`: Add sushiswap support to PancakeSwap

* `@0x/contract-artifacts`: Regenerate artifacts
`@0x/contract-wrappers`: Regenerate wrappers

* `@0x/contract-addresses`: Add BSC addresses

Co-authored-by: mzhu25 <mchl.zhu.96@gmail.com>

Co-authored-by: mzhu25 <mchl.zhu.96@gmail.com>

* feat: Better chain support (#163)

* feat: Better chain support

* feat: better chain support refactor deployment constants (#166)

* proliferate the chainId

* Refactor sampler to remove DeploymentConstants dependency and fixed addresses

* Rework WETH out, replacing with address(0)

* wat

* hack DeploymentConstants for now

* proliferate the chainId

* Refactor sampler to remove DeploymentConstants dependency and fixed addresses

* remove duped network addresses

* Rework the bridge source encoder

* Use the constants NATIVE_FEE_TOKEN in EP consumer

* `@0x/contract-addresses`: Fix WBNB address (#170)

Co-authored-by: Lawrence Forman <lawrence@0xproject.com>

* multichain enable cakez vip (#171)

* feat: Better chain support

* feat: better chain support refactor deployment constants (#166)

* proliferate the chainId

* Refactor sampler to remove DeploymentConstants dependency and fixed addresses

* Rework WETH out, replacing with address(0)

* wat

* hack DeploymentConstants for now

* proliferate the chainId

* Refactor sampler to remove DeploymentConstants dependency and fixed addresses

* remove duped network addresses

* `asset-swapper`: enable pancake VIP route generation

Co-authored-by: Jacob Evans <jacob@dekz.net>
Co-authored-by: Lawrence Forman <me@merklejerk.com>

* `@0x/contracts-zero-ex`: Fix `PancakeSwapFeature` sushi values (#172)

* `@0x/contracts-zero-ex`: Fix `PancakeSwapFeature` sushi values

* `@0x/contracts-zero-ex`: I am a bad protocologist

Co-authored-by: Lawrence Forman <me@merklejerk.com>

* feat: BSC Nerve + Dodo + Nerve + Ellipsis (#181)

* feat: BSC Nerve + DODO v1

* CHANGELOGs

* Remove extra balance fetch

* Add Belt

* Added Ellipsis

* Update FQT address

* `@0x/contracts-zero-ex`: Delete TokenSpenderFeature and get stuff compiling

* `@0x/asset-swapper`: fix compilation

* prettier

* `@0x/asset-swapper`: Truncate LiquidityProvider source ID name

* Update packages/asset-swapper/src/utils/market_operation_utils/sampler_operations.ts

Co-authored-by: Jacob Evans <jacob@dekz.net>

* Update packages/asset-swapper/src/utils/market_operation_utils/sampler_operations.ts

Co-authored-by: Jacob Evans <jacob@dekz.net>

* `@0x/contracts-zero-ex`: Fix BakerySwap on PackageSwapFeature (#190)

* address review comments

Co-authored-by: mzhu25 <mchl.zhu.96@gmail.com>
Co-authored-by: Jacob Evans <jacob@dekz.net>
Co-authored-by: Lawrence Forman <me@merklejerk.com>
2021-03-31 18:49:44 -04:00

223 lines
8.8 KiB
TypeScript

import { artifacts as erc20Artifacts, DummyERC20TokenContract } from '@0x/contracts-erc20';
import { blockchainTests, constants, expect, verifyEventsFromLogs } from '@0x/contracts-test-utils';
import { BigNumber, OwnableRevertErrors, ZeroExRevertErrors } from '@0x/utils';
import { IOwnableFeatureContract, IZeroExContract, LiquidityProviderFeatureContract } from '../../src/wrappers';
import { artifacts } from '../artifacts';
import { abis } from '../utils/abis';
import { fullMigrateAsync } from '../utils/migration';
import {
LiquidityProviderSandboxContract,
TestLiquidityProviderContract,
TestLiquidityProviderEvents,
TestWethContract,
} from '../wrappers';
blockchainTests('LiquidityProvider feature', env => {
let zeroEx: IZeroExContract;
let feature: LiquidityProviderFeatureContract;
let sandbox: LiquidityProviderSandboxContract;
let liquidityProvider: TestLiquidityProviderContract;
let token: DummyERC20TokenContract;
let weth: TestWethContract;
let owner: string;
let taker: string;
before(async () => {
[owner, taker] = await env.getAccountAddressesAsync();
zeroEx = await fullMigrateAsync(owner, env.provider, env.txDefaults, {});
token = await DummyERC20TokenContract.deployFrom0xArtifactAsync(
erc20Artifacts.DummyERC20Token,
env.provider,
env.txDefaults,
erc20Artifacts,
constants.DUMMY_TOKEN_NAME,
constants.DUMMY_TOKEN_SYMBOL,
constants.DUMMY_TOKEN_DECIMALS,
constants.DUMMY_TOKEN_TOTAL_SUPPLY,
);
await token.setBalance(taker, constants.INITIAL_ERC20_BALANCE).awaitTransactionSuccessAsync();
weth = await TestWethContract.deployFrom0xArtifactAsync(
artifacts.TestWeth,
env.provider,
env.txDefaults,
artifacts,
);
await token
.approve(zeroEx.address, constants.INITIAL_ERC20_ALLOWANCE)
.awaitTransactionSuccessAsync({ from: taker });
feature = new LiquidityProviderFeatureContract(zeroEx.address, env.provider, env.txDefaults, abis);
sandbox = await LiquidityProviderSandboxContract.deployFrom0xArtifactAsync(
artifacts.LiquidityProviderSandbox,
env.provider,
env.txDefaults,
artifacts,
zeroEx.address,
);
const featureImpl = await LiquidityProviderFeatureContract.deployFrom0xArtifactAsync(
artifacts.LiquidityProviderFeature,
env.provider,
env.txDefaults,
artifacts,
sandbox.address,
);
await new IOwnableFeatureContract(zeroEx.address, env.provider, env.txDefaults, abis)
.migrate(featureImpl.address, featureImpl.migrate().getABIEncodedTransactionData(), owner)
.awaitTransactionSuccessAsync();
liquidityProvider = await TestLiquidityProviderContract.deployFrom0xArtifactAsync(
artifacts.TestLiquidityProvider,
env.provider,
env.txDefaults,
artifacts,
token.address,
weth.address,
);
});
blockchainTests.resets('Sandbox', () => {
it('Cannot call sandbox `executeSellTokenForToken` function directly', async () => {
const tx = sandbox
.executeSellTokenForToken(
liquidityProvider.address,
token.address,
weth.address,
taker,
constants.ZERO_AMOUNT,
constants.NULL_BYTES,
)
.awaitTransactionSuccessAsync({ from: taker });
return expect(tx).to.revertWith(new OwnableRevertErrors.OnlyOwnerError(taker));
});
it('Cannot call sandbox `executeSellEthForToken` function directly', async () => {
const tx = sandbox
.executeSellEthForToken(
liquidityProvider.address,
token.address,
taker,
constants.ZERO_AMOUNT,
constants.NULL_BYTES,
)
.awaitTransactionSuccessAsync({ from: taker });
return expect(tx).to.revertWith(new OwnableRevertErrors.OnlyOwnerError(taker));
});
it('Cannot call sandbox `executeSellTokenForEth` function directly', async () => {
const tx = sandbox
.executeSellTokenForEth(
liquidityProvider.address,
token.address,
taker,
constants.ZERO_AMOUNT,
constants.NULL_BYTES,
)
.awaitTransactionSuccessAsync({ from: taker });
return expect(tx).to.revertWith(new OwnableRevertErrors.OnlyOwnerError(taker));
});
});
blockchainTests.resets('Swap', () => {
const ETH_TOKEN_ADDRESS = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE';
it('Successfully executes an ERC20-ERC20 swap', async () => {
const tx = await feature
.sellToLiquidityProvider(
token.address,
weth.address,
liquidityProvider.address,
constants.NULL_ADDRESS,
constants.ONE_ETHER,
constants.ZERO_AMOUNT,
constants.NULL_BYTES,
)
.awaitTransactionSuccessAsync({ from: taker });
verifyEventsFromLogs(
tx.logs,
[
{
inputToken: token.address,
outputToken: weth.address,
recipient: taker,
minBuyAmount: constants.ZERO_AMOUNT,
inputTokenBalance: constants.ONE_ETHER,
},
],
TestLiquidityProviderEvents.SellTokenForToken,
);
});
it('Reverts if cannot fulfill the minimum buy amount', async () => {
const minBuyAmount = new BigNumber(1);
const tx = feature
.sellToLiquidityProvider(
token.address,
weth.address,
liquidityProvider.address,
constants.NULL_ADDRESS,
constants.ONE_ETHER,
minBuyAmount,
constants.NULL_BYTES,
)
.awaitTransactionSuccessAsync({ from: taker });
return expect(tx).to.revertWith(
new ZeroExRevertErrors.LiquidityProvider.LiquidityProviderIncompleteSellError(
liquidityProvider.address,
weth.address,
token.address,
constants.ONE_ETHER,
constants.ZERO_AMOUNT,
minBuyAmount,
),
);
});
it('Successfully executes an ETH-ERC20 swap', async () => {
const tx = await feature
.sellToLiquidityProvider(
ETH_TOKEN_ADDRESS,
token.address,
liquidityProvider.address,
constants.NULL_ADDRESS,
constants.ONE_ETHER,
constants.ZERO_AMOUNT,
constants.NULL_BYTES,
)
.awaitTransactionSuccessAsync({ from: taker, value: constants.ONE_ETHER });
verifyEventsFromLogs(
tx.logs,
[
{
outputToken: token.address,
recipient: taker,
minBuyAmount: constants.ZERO_AMOUNT,
ethBalance: constants.ONE_ETHER,
},
],
TestLiquidityProviderEvents.SellEthForToken,
);
});
it('Successfully executes an ERC20-ETH swap', async () => {
const tx = await feature
.sellToLiquidityProvider(
token.address,
ETH_TOKEN_ADDRESS,
liquidityProvider.address,
constants.NULL_ADDRESS,
constants.ONE_ETHER,
constants.ZERO_AMOUNT,
constants.NULL_BYTES,
)
.awaitTransactionSuccessAsync({ from: taker });
verifyEventsFromLogs(
tx.logs,
[
{
inputToken: token.address,
recipient: taker,
minBuyAmount: constants.ZERO_AMOUNT,
inputTokenBalance: constants.ONE_ETHER,
},
],
TestLiquidityProviderEvents.SellTokenForEth,
);
});
});
});