* 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>
223 lines
8.8 KiB
TypeScript
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,
|
|
);
|
|
});
|
|
});
|
|
});
|