Compare commits

...

13 Commits

Author SHA1 Message Date
Jacob Evans
f94ff7551f Add an includedSources=Uniswap_V2 test 2022-03-11 20:00:08 +10:00
Jacob Evans
0174feda36 big test exploration 2022-02-09 10:17:31 +10:00
Jacob Evans
2924783109 measure gas used 2022-02-03 16:42:54 +10:00
Jacob Evans
d57e8f6478 Example Curve Sampler 2022-02-02 09:43:09 +10:00
Jacob Evans
82752ad6ed munge to work with sol-compiler and contracts-gen 2022-02-02 09:11:07 +10:00
Jacob Evans
5ba89a86af Allow tests to be skipped 2022-02-02 08:46:44 +10:00
Jacob Evans
4d94588203 move foundry.toml 2022-02-02 08:30:35 +10:00
Jacob Evans
7e84dc7bea foundry test 2022-02-01 11:52:55 +10:00
Jacob Evans
240e0d2ae4 Update tests 2022-01-31 19:16:27 +10:00
Jacob Evans
83d6533854 Update for buys 2022-01-25 12:03:15 +10:00
Jacob Evans
38662a209c Move some old functions to internal, fix MultiHop 2022-01-25 09:49:57 +10:00
Jacob Evans
ee5197d474 update to internal SAMPLE_VALUES 2022-01-25 08:27:02 +10:00
Jacob Evans
7ac97533d0 chore: Use global sample values for reduced payloads 2022-01-24 14:15:05 +10:00
50 changed files with 2553 additions and 369 deletions

View File

@@ -1,2 +1,4 @@
**/generated-artifacts
**/generated-wrappers
cache
out

View File

@@ -0,0 +1,6 @@
[default]
src = 'src'
test = 'test'
out = 'out'
libs = ['lib']
remappings = ['ds-test/=lib/ds-test/src/']

View File

@@ -20,8 +20,6 @@
pragma solidity ^0.6;
pragma experimental ABIEncoderV2;
import "@0x/contracts-utils/contracts/src/v06/LibMathV06.sol";
contract ApproximateBuys {

View File

@@ -21,9 +21,12 @@ pragma solidity ^0.6;
pragma experimental ABIEncoderV2;
import "./interfaces/IBalancer.sol";
import "./SamplerBase.sol";
contract BalancerSampler {
contract BalancerSampler is
SamplerBase
{
/// @dev Base gas limit for Balancer calls.
uint256 constant private BALANCER_CALL_GAS = 300e3; // 300k
@@ -42,6 +45,29 @@ contract BalancerSampler {
uint256 swapFee;
}
/// @dev Sample sell quotes from Balancer.
/// @param poolAddress Address of the Balancer pool to query.
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromBalancerGlobal(
address poolAddress,
address takerToken,
address makerToken
)
public
view
returns (uint256[] memory makerTokenAmounts)
{
makerTokenAmounts = _sampleSellsFromBalancer(
poolAddress,
takerToken,
makerToken,
SAMPLE_VALUES
);
}
/// @dev Sample sell quotes from Balancer.
/// @param poolAddress Address of the Balancer pool to query.
/// @param takerToken Address of the taker token (what to sell).
@@ -49,13 +75,13 @@ contract BalancerSampler {
/// @param takerTokenAmounts Taker token sell amount for each sample.
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromBalancer(
function _sampleSellsFromBalancer(
address poolAddress,
address takerToken,
address makerToken,
uint256[] memory takerTokenAmounts
)
public
internal
view
returns (uint256[] memory makerTokenAmounts)
{
@@ -104,6 +130,29 @@ contract BalancerSampler {
}
}
/// @dev Sample buy quotes from Balancer.
/// @param poolAddress Address of the Balancer pool to query.
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromBalancerGlobal(
address poolAddress,
address takerToken,
address makerToken
)
public
view
returns (uint256[] memory takerTokenAmounts)
{
takerTokenAmounts = _sampleBuysFromBalancer(
poolAddress,
takerToken,
makerToken,
SAMPLE_VALUES
);
}
/// @dev Sample buy quotes from Balancer.
/// @param poolAddress Address of the Balancer pool to query.
/// @param takerToken Address of the taker token (what to sell).
@@ -111,13 +160,13 @@ contract BalancerSampler {
/// @param makerTokenAmounts Maker token buy amount for each sample.
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromBalancer(
function _sampleBuysFromBalancer(
address poolAddress,
address takerToken,
address makerToken,
uint256[] memory makerTokenAmounts
)
public
internal
view
returns (uint256[] memory takerTokenAmounts)
{

View File

@@ -21,6 +21,7 @@ pragma solidity ^0.6;
pragma experimental ABIEncoderV2;
import "./SamplerUtils.sol";
import "./SamplerBase.sol";
/// @dev Minimal Balancer V2 Vault interface
/// for documentation refer to https://github.com/balancer-labs/balancer-core-v2/blob/master/contracts/vault/interfaces/IVault.sol
@@ -53,13 +54,38 @@ interface IAsset {
// solhint-disable-previous-line no-empty-blocks
}
contract BalancerV2Sampler is SamplerUtils {
contract BalancerV2Sampler is
SamplerBase,
SamplerUtils
{
struct BalancerV2PoolInfo {
bytes32 poolId;
address vault;
}
/// @dev Sample sell quotes from Balancer V2.
/// @param poolInfo Struct with pool related data
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromBalancerV2Global(
BalancerV2PoolInfo memory poolInfo,
address takerToken,
address makerToken
)
public
returns (uint256[] memory makerTokenAmounts)
{
makerTokenAmounts = _sampleSellsFromBalancerV2(
poolInfo,
takerToken,
makerToken,
SAMPLE_VALUES
);
}
/// @dev Sample sell quotes from Balancer V2.
/// @param poolInfo Struct with pool related data
/// @param takerToken Address of the taker token (what to sell).
@@ -67,13 +93,13 @@ contract BalancerV2Sampler is SamplerUtils {
/// @param takerTokenAmounts Taker token sell amount for each sample.
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromBalancerV2(
function _sampleSellsFromBalancerV2(
BalancerV2PoolInfo memory poolInfo,
address takerToken,
address makerToken,
uint256[] memory takerTokenAmounts
)
public
internal
returns (uint256[] memory makerTokenAmounts)
{
_assertValidPair(makerToken, takerToken);
@@ -109,6 +135,28 @@ contract BalancerV2Sampler is SamplerUtils {
}
}
/// @dev Sample buy quotes from Balancer V2.
/// @param poolInfo Struct with pool related data
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromBalancerV2Global(
BalancerV2PoolInfo memory poolInfo,
address takerToken,
address makerToken
)
public
returns (uint256[] memory takerTokenAmounts)
{
takerTokenAmounts = _sampleBuysFromBalancerV2(
poolInfo,
takerToken,
makerToken,
SAMPLE_VALUES
);
}
/// @dev Sample buy quotes from Balancer V2.
/// @param poolInfo Struct with pool related data
/// @param takerToken Address of the taker token (what to sell).
@@ -116,13 +164,13 @@ contract BalancerV2Sampler is SamplerUtils {
/// @param makerTokenAmounts Maker token buy amount for each sample.
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromBalancerV2(
function _sampleBuysFromBalancerV2(
BalancerV2PoolInfo memory poolInfo,
address takerToken,
address makerToken,
uint256[] memory makerTokenAmounts
)
public
internal
returns (uint256[] memory takerTokenAmounts)
{
_assertValidPair(makerToken, takerToken);

View File

@@ -21,10 +21,14 @@ pragma solidity ^0.6;
pragma experimental ABIEncoderV2;
import "./interfaces/IBancor.sol";
import "./SamplerBase.sol";
contract CompilerHack {}
contract BancorSampler is CompilerHack {
contract BancorSampler is
SamplerBase,
CompilerHack
{
/// @dev Base gas limit for Bancor calls.
uint256 constant private BANCOR_CALL_GAS = 300e3; // 300k
@@ -38,18 +42,42 @@ contract BancorSampler is CompilerHack {
/// @param opts BancorSamplerOpts The Bancor registry contract address and paths
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @param takerTokenAmounts Taker token sell amount for each sample.
/// @return bancorNetwork the Bancor Network address
/// @return path the selected conversion path from bancor
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromBancor(
function sampleSellsFromBancorGlobal(
BancorSamplerOpts memory opts,
address takerToken,
address makerToken
)
public
view
returns (address bancorNetwork, address[] memory path, uint256[] memory makerTokenAmounts)
{
(bancorNetwork, path, makerTokenAmounts) = _sampleSellsFromBancor(
opts,
takerToken,
makerToken,
SAMPLE_VALUES
);
}
/// @dev Sample sell quotes from Bancor.
/// @param opts BancorSamplerOpts The Bancor registry contract address and paths
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @return bancorNetwork the Bancor Network address
/// @return path the selected conversion path from bancor
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function _sampleSellsFromBancor(
BancorSamplerOpts memory opts,
address takerToken,
address makerToken,
uint256[] memory takerTokenAmounts
)
public
internal
view
returns (address bancorNetwork, address[] memory path, uint256[] memory makerTokenAmounts)
{
@@ -84,21 +112,20 @@ contract BancorSampler is CompilerHack {
/// @param opts BancorSamplerOpts The Bancor registry contract address and paths
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @param makerTokenAmounts Maker token buy amount for each sample.
/// @return bancorNetwork the Bancor Network address
/// @return path the selected conversion path from bancor
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromBancor(
function sampleBuysFromBancorGlobal(
BancorSamplerOpts memory opts,
address takerToken,
address makerToken,
uint256[] memory makerTokenAmounts
address makerToken
)
public
view
returns (address bancorNetwork, address[] memory path, uint256[] memory takerTokenAmounts)
{
takerTokenAmounts = new uint256[](SAMPLE_VALUES.length);
}
function _findBestPath(

View File

@@ -21,7 +21,8 @@ pragma solidity ^0.6;
pragma experimental ABIEncoderV2;
import "./SamplerUtils.sol";
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
import "./interfaces/IERC20TokenV06.sol";
import "./SamplerBase.sol";
// Minimal CToken interface
interface ICToken {
@@ -32,16 +33,36 @@ interface ICToken {
function decimals() external view returns (uint8);
}
contract CompoundSampler is SamplerUtils {
contract CompoundSampler is
SamplerBase,
SamplerUtils
{
uint256 constant private EXCHANGE_RATE_SCALE = 1e10;
function sampleSellsFromCompound(
function sampleSellsFromCompoundGlobal(
ICToken cToken,
IERC20TokenV06 takerToken,
IERC20TokenV06 makerToken
)
public
view
returns (uint256[] memory makerTokenAmounts)
{
makerTokenAmounts = _sampleSellsFromCompound(
cToken,
takerToken,
makerToken,
SAMPLE_VALUES
);
}
function _sampleSellsFromCompound(
ICToken cToken,
IERC20TokenV06 takerToken,
IERC20TokenV06 makerToken,
uint256[] memory takerTokenAmounts
)
public
internal
view
returns (uint256[] memory makerTokenAmounts)
{
@@ -65,13 +86,30 @@ contract CompoundSampler is SamplerUtils {
}
}
function sampleBuysFromCompound(
function sampleBuysFromCompoundGlobal(
ICToken cToken,
IERC20TokenV06 takerToken,
IERC20TokenV06 makerToken
)
public
view
returns (uint256[] memory takerTokenAmounts)
{
takerTokenAmounts = _sampleBuysFromCompound(
cToken,
takerToken,
makerToken,
SAMPLE_VALUES
);
}
function _sampleBuysFromCompound(
ICToken cToken,
IERC20TokenV06 takerToken,
IERC20TokenV06 makerToken,
uint256[] memory makerTokenAmounts
)
public
internal
view
returns (uint256[] memory takerTokenAmounts)
{

View File

@@ -23,9 +23,11 @@ pragma experimental ABIEncoderV2;
import "./interfaces/ICurve.sol";
import "./ApproximateBuys.sol";
import "./SamplerUtils.sol";
import "./SamplerBase.sol";
contract CurveSampler is
SamplerBase,
SamplerUtils,
ApproximateBuys
{
@@ -40,6 +42,29 @@ contract CurveSampler is
/// So a reasonable ceil is 150k per token. Biggest Curve has 4 tokens.
uint256 constant private CURVE_CALL_GAS = 2000e3; // Was 600k for Curve but SnowSwap is using 1500k+
/// @dev Sample sell quotes from Curve.
/// @param curveInfo Curve information specific to this token pair.
/// @param fromTokenIdx Index of the taker token (what to sell).
/// @param toTokenIdx Index of the maker token (what to buy).
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromCurveGlobal(
CurveInfo memory curveInfo,
int128 fromTokenIdx,
int128 toTokenIdx
)
public
view
returns (uint256[] memory makerTokenAmounts)
{
makerTokenAmounts = this.sampleSellsFromCurve(
curveInfo,
fromTokenIdx,
toTokenIdx,
SAMPLE_VALUES
);
}
/// @dev Sample sell quotes from Curve.
/// @param curveInfo Curve information specific to this token pair.
/// @param fromTokenIdx Index of the taker token (what to sell).
@@ -80,6 +105,29 @@ contract CurveSampler is
}
}
/// @dev Sample buy quotes from Curve.
/// @param curveInfo Curve information specific to this token pair.
/// @param fromTokenIdx Index of the taker token (what to sell).
/// @param toTokenIdx Index of the maker token (what to buy).
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromCurveGlobal(
CurveInfo memory curveInfo,
int128 fromTokenIdx,
int128 toTokenIdx
)
public
view
returns (uint256[] memory takerTokenAmounts)
{
takerTokenAmounts = _sampleBuysFromCurve(
curveInfo,
fromTokenIdx,
toTokenIdx,
SAMPLE_VALUES
);
}
/// @dev Sample buy quotes from Curve.
/// @param curveInfo Curve information specific to this token pair.
/// @param fromTokenIdx Index of the taker token (what to sell).
@@ -87,13 +135,13 @@ contract CurveSampler is
/// @param makerTokenAmounts Maker token buy amount for each sample.
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromCurve(
function _sampleBuysFromCurve(
CurveInfo memory curveInfo,
int128 fromTokenIdx,
int128 toTokenIdx,
uint256[] memory makerTokenAmounts
)
public
internal
view
returns (uint256[] memory takerTokenAmounts)
{

View File

@@ -22,6 +22,7 @@ pragma experimental ABIEncoderV2;
import "./ApproximateBuys.sol";
import "./SamplerUtils.sol";
import "./SamplerBase.sol";
interface IDODOZoo {
@@ -38,6 +39,7 @@ interface IDODO {
}
contract DODOSampler is
SamplerBase,
SamplerUtils,
ApproximateBuys
{
@@ -49,6 +51,31 @@ contract DODOSampler is
address helper;
}
/// @dev Sample sell quotes from DODO.
/// @param opts DODOSamplerOpts DODO Registry and helper addresses
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @return sellBase whether the bridge needs to sell the base token
/// @return pool the DODO pool address
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromDODOGlobal(
DODOSamplerOpts memory opts,
address takerToken,
address makerToken
)
public
view
returns (bool sellBase, address pool, uint256[] memory makerTokenAmounts)
{
(sellBase, pool, makerTokenAmounts) = this.sampleSellsFromDODO(
opts,
takerToken,
makerToken,
SAMPLE_VALUES
);
}
/// @dev Sample sell quotes from DODO.
/// @param opts DODOSamplerOpts DODO Registry and helper addresses
/// @param takerToken Address of the taker token (what to sell).
@@ -107,6 +134,31 @@ contract DODOSampler is
}
}
/// @dev Sample buy quotes from DODO.
/// @param opts DODOSamplerOpts DODO Registry and helper addresses
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @return sellBase whether the bridge needs to sell the base token
/// @return pool the DODO pool address
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromDODOGlobal(
DODOSamplerOpts memory opts,
address takerToken,
address makerToken
)
public
view
returns (bool sellBase, address pool, uint256[] memory takerTokenAmounts)
{
(sellBase, pool, takerTokenAmounts) = _sampleBuysFromDODO(
opts,
takerToken,
makerToken,
SAMPLE_VALUES
);
}
/// @dev Sample buy quotes from DODO.
/// @param opts DODOSamplerOpts DODO Registry and helper addresses
/// @param takerToken Address of the taker token (what to sell).
@@ -116,13 +168,13 @@ contract DODOSampler is
/// @return pool the DODO pool address
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromDODO(
function _sampleBuysFromDODO(
DODOSamplerOpts memory opts,
address takerToken,
address makerToken,
uint256[] memory makerTokenAmounts
)
public
internal
view
returns (bool sellBase, address pool, uint256[] memory takerTokenAmounts)
{

View File

@@ -22,6 +22,7 @@ pragma experimental ABIEncoderV2;
import "./ApproximateBuys.sol";
import "./SamplerUtils.sol";
import "./SamplerBase.sol";
interface IDODOV2Registry {
function getDODOPool(address baseToken, address quoteToken)
@@ -43,6 +44,7 @@ interface IDODOV2Pool {
}
contract DODOV2Sampler is
SamplerBase,
SamplerUtils,
ApproximateBuys
{
@@ -50,6 +52,34 @@ contract DODOV2Sampler is
/// @dev Gas limit for DODO V2 calls.
uint256 constant private DODO_V2_CALL_GAS = 300e3; // 300k
/// @dev Sample sell quotes from DODO V2.
/// @param registry Address of the registry to look up.
/// @param offset offset index for the pool in the registry.
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @return sellBase whether the bridge needs to sell the base token
/// @return pool the DODO pool address
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromDODOV2Global(
address registry,
uint256 offset,
address takerToken,
address makerToken
)
public
view
returns (bool sellBase, address pool, uint256[] memory makerTokenAmounts)
{
(sellBase, pool, makerTokenAmounts) = this.sampleSellsFromDODOV2(
registry,
offset,
takerToken,
makerToken,
SAMPLE_VALUES
);
}
/// @dev Sample sell quotes from DODO V2.
/// @param registry Address of the registry to look up.
/// @param offset offset index for the pool in the registry.
@@ -95,6 +125,34 @@ contract DODOV2Sampler is
}
}
/// @dev Sample buy quotes from DODO.
/// @param registry Address of the registry to look up.
/// @param offset offset index for the pool in the registry.
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @return sellBase whether the bridge needs to sell the base token
/// @return pool the DODO pool address
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromDODOV2Global(
address registry,
uint256 offset,
address takerToken,
address makerToken
)
public
view
returns (bool sellBase, address pool, uint256[] memory takerTokenAmounts)
{
(sellBase, pool, takerTokenAmounts) = _sampleBuysFromDODOV2(
registry,
offset,
takerToken,
makerToken,
SAMPLE_VALUES
);
}
/// @dev Sample buy quotes from DODO.
/// @param registry Address of the registry to look up.
/// @param offset offset index for the pool in the registry.
@@ -105,14 +163,14 @@ contract DODOV2Sampler is
/// @return pool the DODO pool address
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromDODOV2(
function _sampleBuysFromDODOV2(
address registry,
uint256 offset,
address takerToken,
address makerToken,
uint256[] memory makerTokenAmounts
)
public
internal
view
returns (bool sellBase, address pool, uint256[] memory takerTokenAmounts)
{

View File

@@ -20,6 +20,8 @@
pragma solidity ^0.6;
pragma experimental ABIEncoderV2;
import "./SamplerBase.sol";
interface IKyberDmmPool {
function totalSupply()
@@ -53,11 +55,32 @@ interface IKyberDmmRouter {
contract KyberDmmSampler
contract KyberDmmSampler is
SamplerBase
{
/// @dev Gas limit for KyberDmm calls.
uint256 constant private KYBER_DMM_CALL_GAS = 150e3; // 150k
/// @dev Sample sell quotes from KyberDmm.
/// @param router Router to look up tokens and amounts
/// @param path Token route. Should be takerToken -> makerToken
/// @return pools The pool addresses involved in the multi path trade
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromKyberDmmGlobal(
address router,
address[] memory path
)
public
view
returns (address[] memory pools, uint256[] memory makerTokenAmounts)
{
(pools, makerTokenAmounts) = _sampleSellsFromKyberDmm(
router,
path,
SAMPLE_VALUES
);
}
/// @dev Sample sell quotes from KyberDmm.
/// @param router Router to look up tokens and amounts
/// @param path Token route. Should be takerToken -> makerToken
@@ -65,12 +88,12 @@ contract KyberDmmSampler
/// @return pools The pool addresses involved in the multi path trade
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromKyberDmm(
function _sampleSellsFromKyberDmm(
address router,
address[] memory path,
uint256[] memory takerTokenAmounts
)
public
internal
view
returns (address[] memory pools, uint256[] memory makerTokenAmounts)
{
@@ -99,6 +122,27 @@ contract KyberDmmSampler
}
}
/// @dev Sample buy quotes from KyberDmm.
/// @param router Router to look up tokens and amounts
/// @param path Token route. Should be takerToken -> makerToken.
/// @return pools The pool addresses involved in the multi path trade
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromKyberDmmGlobal(
address router,
address[] memory path
)
public
view
returns (address[] memory pools, uint256[] memory takerTokenAmounts)
{
(pools, takerTokenAmounts) = _sampleBuysFromKyberDmm(
router,
path,
SAMPLE_VALUES
);
}
/// @dev Sample buy quotes from KyberDmm.
/// @param router Router to look up tokens and amounts
/// @param path Token route. Should be takerToken -> makerToken.
@@ -106,12 +150,12 @@ contract KyberDmmSampler
/// @return pools The pool addresses involved in the multi path trade
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromKyberDmm(
function _sampleBuysFromKyberDmm(
address router,
address[] memory path,
uint256[] memory makerTokenAmounts
)
public
internal
view
returns (address[] memory pools, uint256[] memory takerTokenAmounts)
{

View File

@@ -23,9 +23,11 @@ pragma experimental ABIEncoderV2;
import "./interfaces/IKyberNetwork.sol";
import "./ApproximateBuys.sol";
import "./SamplerUtils.sol";
import "./SamplerBase.sol";
contract KyberSampler is
SamplerBase,
SamplerUtils,
ApproximateBuys
{
@@ -42,6 +44,30 @@ contract KyberSampler is
bytes hint;
}
/// @dev Sample sell quotes from Kyber.
/// @param opts KyberSamplerOpts The nth reserve
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @return reserveId The id of the reserve found at reserveOffset
/// @return hint The hint for the selected reserve
/// @return makerTokenAmounts Maker amounts bought at each taker token amount.
function sampleSellsFromKyberNetworkGlobal(
KyberSamplerOpts memory opts,
address takerToken,
address makerToken
)
public
view
returns (bytes32 reserveId, bytes memory hint, uint256[] memory makerTokenAmounts)
{
(reserveId, hint, makerTokenAmounts) = this.sampleSellsFromKyberNetwork(
opts,
takerToken,
makerToken,
SAMPLE_VALUES
);
}
/// @dev Sample sell quotes from Kyber.
/// @param opts KyberSamplerOpts The nth reserve
/// @param takerToken Address of the taker token (what to sell).
@@ -85,6 +111,30 @@ contract KyberSampler is
}
}
/// @dev Sample buy quotes from Kyber.
/// @param opts KyberSamplerOpts The nth reserve
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @return reserveId The id of the reserve found at reserveOffset
/// @return hint The hint for the selected reserve
/// @return takerTokenAmounts Taker amounts sold at each maker token amount.
function sampleBuysFromKyberNetworkGlobal(
KyberSamplerOpts memory opts,
address takerToken,
address makerToken
)
public
view
returns (bytes32 reserveId, bytes memory hint, uint256[] memory takerTokenAmounts)
{
(reserveId, hint, takerTokenAmounts) = _sampleBuysFromKyberNetwork(
opts,
takerToken,
makerToken,
SAMPLE_VALUES
);
}
/// @dev Sample buy quotes from Kyber.
/// @param opts KyberSamplerOpts The nth reserve
/// @param takerToken Address of the taker token (what to sell).
@@ -93,13 +143,13 @@ contract KyberSampler is
/// @return reserveId The id of the reserve found at reserveOffset
/// @return hint The hint for the selected reserve
/// @return takerTokenAmounts Taker amounts sold at each maker token amount.
function sampleBuysFromKyberNetwork(
function _sampleBuysFromKyberNetwork(
KyberSamplerOpts memory opts,
address takerToken,
address makerToken,
uint256[] memory makerTokenAmounts
)
public
internal
view
returns (bytes32 reserveId, bytes memory hint, uint256[] memory takerTokenAmounts)
{

View File

@@ -0,0 +1,66 @@
/*
Copyright 2022 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.6;
library LibBytes {
using LibBytes for bytes;
/// @dev Reads a uint256 value from a position in a byte array.
/// @param b Byte array containing a uint256 value.
/// @param index Index in byte array of uint256 value.
/// @return result value from byte array.
function readUint256(
bytes memory b,
uint256 index
)
internal
pure
returns (uint256 result)
{
result = uint256(readBytes32(b, index));
return result;
}
/// @dev Reads a bytes32 value from a position in a byte array.
/// @param b Byte array containing a bytes32 value.
/// @param index Index in byte array of bytes32 value.
/// @return result bytes32 value from byte array.
function readBytes32(
bytes memory b,
uint256 index
)
internal
pure
returns (bytes32 result)
{
if (b.length < index + 32) {
revert("Invalid bytes32 index");
}
// Arrays are prefixed by a 256 bit length parameter
index += 32;
// Read the bytes32 from array memory
assembly {
result := mload(add(b, index))
}
return result;
}
}

View File

@@ -0,0 +1,199 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2022 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.6;
library LibSafeMath {
using LibSafeMath for uint256;
function safeMul(uint256 a, uint256 b)
internal
pure
returns (uint256)
{
if (a == 0) {
return 0;
}
uint256 c = a * b;
if (c / a != b) {
revert("SafeMath: multiplication overflow");
}
return c;
}
function safeDiv(uint256 a, uint256 b)
internal
pure
returns (uint256)
{
if (b == 0) {
revert("SafeMath: division by 0");
}
uint256 c = a / b;
return c;
}
function safeSub(uint256 a, uint256 b)
internal
pure
returns (uint256)
{
if (b > a) {
revert("SafeMath: subtraction underflow");
}
return a - b;
}
function safeAdd(uint256 a, uint256 b)
internal
pure
returns (uint256)
{
uint256 c = a + b;
if (c < a) {
revert("SafeMath: addition overflow");
}
return c;
}
function max256(uint256 a, uint256 b)
internal
pure
returns (uint256)
{
return a >= b ? a : b;
}
function min256(uint256 a, uint256 b)
internal
pure
returns (uint256)
{
return a < b ? a : b;
}
function safeMul128(uint128 a, uint128 b)
internal
pure
returns (uint128)
{
if (a == 0) {
return 0;
}
uint128 c = a * b;
if (c / a != b) {
revert("SafeMath: multiplication overflow");
}
return c;
}
function safeDiv128(uint128 a, uint128 b)
internal
pure
returns (uint128)
{
if (b == 0) {
revert("SafeMath: division by 0");
}
uint128 c = a / b;
return c;
}
function safeSub128(uint128 a, uint128 b)
internal
pure
returns (uint128)
{
if (b > a) {
revert("SafeMath: subtraction underflow");
}
return a - b;
}
function safeAdd128(uint128 a, uint128 b)
internal
pure
returns (uint128)
{
uint128 c = a + b;
if (c < a) {
revert("SafeMath: addition overflow");
}
return c;
}
function max128(uint128 a, uint128 b)
internal
pure
returns (uint128)
{
return a >= b ? a : b;
}
function min128(uint128 a, uint128 b)
internal
pure
returns (uint128)
{
return a < b ? a : b;
}
function safeDowncastToUint128(uint256 a)
internal
pure
returns (uint128)
{
if (a > type(uint128).max) {
revert("SafeMath: cannot downcast uint256 to uint128");
}
return uint128(a);
}
function getPartialAmountCeil(
uint256 numerator,
uint256 denominator,
uint256 target
)
internal
pure
returns (uint256 partialAmount)
{
// safeDiv computes `floor(a / b)`. We use the identity (a, b integer):
// ceil(a / b) = floor((a + b - 1) / b)
// To implement `ceil(a / b)` using safeDiv.
partialAmount = numerator.safeMul(target)
.safeAdd(denominator.safeSub(1))
.safeDiv(denominator);
return partialAmount;
}
function getPartialAmountFloor(
uint256 numerator,
uint256 denominator,
uint256 target
)
internal
pure
returns (uint256 partialAmount)
{
partialAmount = numerator.safeMul(target).safeDiv(denominator);
return partialAmount;
}
}

View File

@@ -21,13 +21,40 @@ pragma solidity ^0.6;
pragma experimental ABIEncoderV2;
import "./SamplerUtils.sol";
import "./SamplerBase.sol";
contract LidoSampler is SamplerUtils {
contract LidoSampler is
SamplerBase,
SamplerUtils
{
struct LidoInfo {
address stEthToken;
address wethToken;
}
/// @dev Sample sell quotes from Lido
/// @param lidoInfo Info regarding a specific Lido deployment
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromLidoGlobal(
LidoInfo memory lidoInfo,
address takerToken,
address makerToken
)
public
returns (uint256[] memory makerTokenAmounts)
{
makerTokenAmounts = _sampleSellsFromLido(
lidoInfo,
takerToken,
makerToken,
SAMPLE_VALUES
);
}
/// @dev Sample sell quotes from Lido
/// @param lidoInfo Info regarding a specific Lido deployment
/// @param takerToken Address of the taker token (what to sell).
@@ -35,13 +62,13 @@ contract LidoSampler is SamplerUtils {
/// @param takerTokenAmounts Taker token sell amount for each sample.
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromLido(
function _sampleSellsFromLido(
LidoInfo memory lidoInfo,
address takerToken,
address makerToken,
uint256[] memory takerTokenAmounts
)
public
internal
pure
returns (uint256[] memory)
{
@@ -58,6 +85,29 @@ contract LidoSampler is SamplerUtils {
return takerTokenAmounts;
}
/// @dev Sample buy quotes from Lido.
/// @param lidoInfo Info regarding a specific Lido deployment
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromLidoGlobal(
LidoInfo memory lidoInfo,
address takerToken,
address makerToken
)
public
view
returns (uint256[] memory takerTokenAmounts)
{
takerTokenAmounts = _sampleBuysFromLido(
lidoInfo,
takerToken,
makerToken,
SAMPLE_VALUES
);
}
/// @dev Sample buy quotes from Lido.
/// @param lidoInfo Info regarding a specific Lido deployment
/// @param takerToken Address of the taker token (what to sell).
@@ -65,13 +115,13 @@ contract LidoSampler is SamplerUtils {
/// @param makerTokenAmounts Maker token buy amount for each sample.
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromLido(
function _sampleBuysFromLido(
LidoInfo memory lidoInfo,
address takerToken,
address makerToken,
uint256[] memory makerTokenAmounts
)
public
internal
pure
returns (uint256[] memory)
{

View File

@@ -20,19 +20,43 @@
pragma solidity ^0.6;
pragma experimental ABIEncoderV2;
import "@0x/contracts-utils/contracts/src/v06/LibBytesV06.sol";
import "@0x/contracts-zero-ex/contracts/src/vendor/ILiquidityProvider.sol";
import "./interfaces/ILiquidityProvider.sol";
import "./ApproximateBuys.sol";
import "./SamplerUtils.sol";
import "./SamplerBase.sol";
contract LiquidityProviderSampler is
SamplerBase,
SamplerUtils,
ApproximateBuys
{
/// @dev Default gas limit for liquidity provider calls.
uint256 constant private DEFAULT_CALL_GAS = 400e3; // 400k
/// @dev Sample sell quotes from an arbitrary on-chain liquidity provider.
/// @param providerAddress Address of the liquidity provider.
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromLiquidityProviderGlobal(
address providerAddress,
address takerToken,
address makerToken
)
public
view
returns (uint256[] memory makerTokenAmounts)
{
makerTokenAmounts = this.sampleSellsFromLiquidityProvider(
providerAddress,
takerToken,
makerToken,
SAMPLE_VALUES
);
}
/// @dev Sample sell quotes from an arbitrary on-chain liquidity provider.
/// @param providerAddress Address of the liquidity provider.
/// @param takerToken Address of the taker token (what to sell).
@@ -77,6 +101,29 @@ contract LiquidityProviderSampler is
}
}
/// @dev Sample buy quotes from an arbitrary on-chain liquidity provider.
/// @param providerAddress Address of the liquidity provider.
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromLiquidityProviderGlobal(
address providerAddress,
address takerToken,
address makerToken
)
public
view
returns (uint256[] memory takerTokenAmounts)
{
(takerTokenAmounts) = _sampleBuysFromLiquidityProvider(
providerAddress,
takerToken,
makerToken,
SAMPLE_VALUES
);
}
/// @dev Sample buy quotes from an arbitrary on-chain liquidity provider.
/// @param providerAddress Address of the liquidity provider.
/// @param takerToken Address of the taker token (what to sell).
@@ -84,13 +131,13 @@ contract LiquidityProviderSampler is
/// @param makerTokenAmounts Maker token buy amount for each sample.
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromLiquidityProvider(
function _sampleBuysFromLiquidityProvider(
address providerAddress,
address takerToken,
address makerToken,
uint256[] memory makerTokenAmounts
)
public
internal
view
returns (uint256[] memory takerTokenAmounts)
{

View File

@@ -23,15 +23,39 @@ pragma experimental ABIEncoderV2;
import "./interfaces/IMStable.sol";
import "./ApproximateBuys.sol";
import "./SamplerUtils.sol";
import "./SamplerBase.sol";
contract MStableSampler is
SamplerBase,
SamplerUtils,
ApproximateBuys
{
/// @dev Default gas limit for mStable calls.
uint256 constant private DEFAULT_CALL_GAS = 800e3; // 800k
/// @dev Sample sell quotes from the mStable contract
/// @param router Address of the mStable contract
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromMStableGlobal(
address router,
address takerToken,
address makerToken
)
public
view
returns (uint256[] memory makerTokenAmounts)
{
makerTokenAmounts = this.sampleSellsFromMStable(
router,
takerToken,
makerToken,
SAMPLE_VALUES
);
}
/// @dev Sample sell quotes from the mStable contract
/// @param router Address of the mStable contract
/// @param takerToken Address of the taker token (what to sell).
@@ -73,6 +97,29 @@ contract MStableSampler is
}
}
/// @dev Sample buy quotes from MStable contract
/// @param router Address of the mStable contract
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromMStableGlobal(
address router,
address takerToken,
address makerToken
)
public
view
returns (uint256[] memory takerTokenAmounts)
{
(takerTokenAmounts) = _sampleBuysFromMStable(
router,
takerToken,
makerToken,
SAMPLE_VALUES
);
}
/// @dev Sample buy quotes from MStable contract
/// @param router Address of the mStable contract
/// @param takerToken Address of the taker token (what to sell).
@@ -80,13 +127,13 @@ contract MStableSampler is
/// @param makerTokenAmounts Maker token buy amount for each sample.
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromMStable(
function _sampleBuysFromMStable(
address router,
address takerToken,
address makerToken,
uint256[] memory makerTokenAmounts
)
public
internal
view
returns (uint256[] memory takerTokenAmounts)
{

View File

@@ -21,7 +21,8 @@ pragma solidity ^0.6;
pragma experimental ABIEncoderV2;
import "./SamplerUtils.sol";
import "@0x/contracts-utils/contracts/src/v06/LibMathV06.sol";
import "./LibSafeMath.sol";
import "./SamplerBase.sol";
interface IPSM {
// @dev Get the fee for selling USDC to DAI in PSM
@@ -80,9 +81,10 @@ interface IVAT {
}
contract MakerPSMSampler is
SamplerBase,
SamplerUtils
{
using LibSafeMathV06 for uint256;
using LibSafeMath for uint256;
/// @dev Information about which PSM module to use
struct MakerPsmInfo {
@@ -105,13 +107,31 @@ contract MakerPSMSampler is
// See https://github.com/makerdao/dss/blob/master/DEVELOPING.m
/// @dev Sample sell quotes from Maker PSM
function sampleSellsFromMakerPsm(
function sampleSellsFromMakerPsmGlobal(
MakerPsmInfo memory psmInfo,
address takerToken,
address makerToken
)
public
view
returns (uint256[] memory makerTokenAmounts)
{
makerTokenAmounts = _sampleSellsFromMakerPsm(
psmInfo,
takerToken,
makerToken,
SAMPLE_VALUES
);
}
/// @dev Sample sell quotes from Maker PSM
function _sampleSellsFromMakerPsm(
MakerPsmInfo memory psmInfo,
address takerToken,
address makerToken,
uint256[] memory takerTokenAmounts
)
public
internal
view
returns (uint256[] memory makerTokenAmounts)
{
@@ -137,13 +157,30 @@ contract MakerPSMSampler is
}
}
function sampleBuysFromMakerPsm(
function sampleBuysFromMakerPsmGlobal(
MakerPsmInfo memory psmInfo,
address takerToken,
address makerToken
)
public
view
returns (uint256[] memory takerTokenAmounts)
{
(takerTokenAmounts) = _sampleBuysFromMakerPsm(
psmInfo,
takerToken,
makerToken,
SAMPLE_VALUES
);
}
function _sampleBuysFromMakerPsm(
MakerPsmInfo memory psmInfo,
address takerToken,
address makerToken,
uint256[] memory makerTokenAmounts
)
public
internal
view
returns (uint256[] memory takerTokenAmounts)
{

View File

@@ -23,15 +23,41 @@ pragma experimental ABIEncoderV2;
import "./interfaces/IMooniswap.sol";
import "./ApproximateBuys.sol";
import "./SamplerUtils.sol";
import "./SamplerBase.sol";
contract MooniswapSampler is
SamplerBase,
SamplerUtils,
ApproximateBuys
{
/// @dev Gas limit for Mooniswap calls.
uint256 constant private MOONISWAP_CALL_GAS = 150e3; // 150k
/// @dev Sample sell quotes from Mooniswap.
/// @param registry Address of the Mooniswap Registry.
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @return pool The contract address for the pool
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromMooniswapGlobal(
address registry,
address takerToken,
address makerToken
)
public
view
returns (IMooniswap pool, uint256[] memory makerTokenAmounts)
{
(pool, makerTokenAmounts) = this.sampleSellsFromMooniswap(
registry,
takerToken,
makerToken,
SAMPLE_VALUES
);
}
/// @dev Sample sell quotes from Mooniswap.
/// @param registry Address of the Mooniswap Registry.
/// @param takerToken Address of the taker token (what to sell).
@@ -112,6 +138,30 @@ contract MooniswapSampler is
}
}
/// @dev Sample buy quotes from Mooniswap.
/// @param registry Address of the Mooniswap Registry.
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @return pool The contract address for the pool
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromMooniswapGlobal(
address registry,
address takerToken,
address makerToken
)
public
view
returns (IMooniswap pool, uint256[] memory takerTokenAmounts)
{
(pool, takerTokenAmounts) = _sampleBuysFromMooniswap(
registry,
takerToken,
makerToken,
SAMPLE_VALUES
);
}
/// @dev Sample buy quotes from Mooniswap.
/// @param registry Address of the Mooniswap Registry.
/// @param takerToken Address of the taker token (what to sell).
@@ -120,13 +170,13 @@ contract MooniswapSampler is
/// @return pool The contract address for the pool
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromMooniswap(
function _sampleBuysFromMooniswap(
address registry,
address takerToken,
address makerToken,
uint256[] memory makerTokenAmounts
)
public
internal
view
returns (IMooniswap pool, uint256[] memory takerTokenAmounts)
{

View File

@@ -20,11 +20,8 @@
pragma solidity ^0.6;
pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
import "@0x/contracts-utils/contracts/src/v06/LibMathV06.sol";
import "@0x/contracts-utils/contracts/src/v06/LibBytesV06.sol";
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
import "./interfaces/IERC20TokenV06.sol";
import "./LibSafeMath.sol";
interface IExchange {
@@ -123,8 +120,8 @@ interface IExchange {
}
contract NativeOrderSampler {
using LibSafeMathV06 for uint256;
using LibBytesV06 for bytes;
using LibSafeMath for uint256;
// using LibBytesV06 for bytes;
/// @dev Gas limit for calls to `getOrderFillableTakerAmount()`.
uint256 constant internal DEFAULT_CALL_GAS = 200e3; // 200k
@@ -191,7 +188,7 @@ contract NativeOrderSampler {
// convert them to maker asset amounts.
for (uint256 i = 0; i < orders.length; ++i) {
if (orderFillableMakerAssetAmounts[i] != 0) {
orderFillableMakerAssetAmounts[i] = LibMathV06.getPartialAmountCeil(
orderFillableMakerAssetAmounts[i] = LibSafeMath.getPartialAmountCeil(
orderFillableMakerAssetAmounts[i],
orders[i].takerAmount,
orders[i].makerAmount

View File

@@ -0,0 +1,40 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2021 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.6;
pragma experimental ABIEncoderV2;
contract SamplerBase
{
/// @dev Stored Sample values for each Sampler to pull
uint256[] internal SAMPLE_VALUES = new uint256[](0);
function setSampleValues(uint256[] memory sampleValues)
public
{
SAMPLE_VALUES = sampleValues;
}
modifier resetsSampleValues
{
uint256[] memory sampleValues = SAMPLE_VALUES;
_;
SAMPLE_VALUES = sampleValues;
}
}

View File

@@ -20,7 +20,7 @@
pragma solidity ^0.6;
pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
import "./interfaces/IERC20TokenV06.sol";
contract SamplerUtils {
@@ -34,7 +34,7 @@ contract SamplerUtils {
view
returns (uint8 decimals)
{
return LibERC20TokenV06.compatDecimals(IERC20TokenV06(tokenAddress));
return IERC20TokenV06(tokenAddress).decimals();
}
function _toSingleValueArray(uint256 v)

View File

@@ -23,9 +23,11 @@ pragma experimental ABIEncoderV2;
import "./ApproximateBuys.sol";
import "./interfaces/IShell.sol";
import "./SamplerUtils.sol";
import "./SamplerBase.sol";
contract ShellSampler is
SamplerBase,
SamplerUtils,
ApproximateBuys
{
@@ -37,6 +39,29 @@ contract ShellSampler is
/// @dev Default gas limit for Shell calls.
uint256 constant private DEFAULT_CALL_GAS = 300e3; // 300k
/// @dev Sample sell quotes from the Shell pool contract
/// @param pool Address of the Shell pool contract
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromShellGlobal(
address pool,
address takerToken,
address makerToken
)
public
view
returns (uint256[] memory makerTokenAmounts)
{
makerTokenAmounts = this.sampleSellsFromShell(
pool,
takerToken,
makerToken,
SAMPLE_VALUES
);
}
/// @dev Sample sell quotes from the Shell pool contract
/// @param pool Address of the Shell pool contract
/// @param takerToken Address of the taker token (what to sell).
@@ -73,6 +98,29 @@ contract ShellSampler is
}
}
/// @dev Sample buy quotes from Shell pool contract
/// @param pool Address of the Shell pool contract
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromShellGlobal(
address pool,
address takerToken,
address makerToken
)
public
view
returns (uint256[] memory takerTokenAmounts)
{
takerTokenAmounts = _sampleBuysFromShell(
pool,
takerToken,
makerToken,
SAMPLE_VALUES
);
}
/// @dev Sample buy quotes from Shell pool contract
/// @param pool Address of the Shell pool contract
/// @param takerToken Address of the taker token (what to sell).
@@ -80,13 +128,13 @@ contract ShellSampler is
/// @param makerTokenAmounts Maker token buy amount for each sample.
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromShell(
function _sampleBuysFromShell(
address pool,
address takerToken,
address makerToken,
uint256[] memory makerTokenAmounts
)
public
internal
view
returns (uint256[] memory takerTokenAmounts)
{

View File

@@ -24,8 +24,10 @@ pragma experimental ABIEncoderV2;
import "./ApproximateBuys.sol";
import "./SamplerUtils.sol";
import "./interfaces/ISmoothy.sol";
import "./SamplerBase.sol";
contract SmoothySampler is
SamplerBase,
SamplerUtils,
ApproximateBuys
{
@@ -39,6 +41,29 @@ contract SmoothySampler is
/// @dev Base gas limit for Smoothy calls.
uint256 constant private SMOOTHY_CALL_GAS = 600e3;
/// @dev Sample sell quotes from Smoothy.
/// @param smoothyInfo Smoothy information specific to this token pair.
/// @param fromTokenIdx Index of the taker token (what to sell).
/// @param toTokenIdx Index of the maker token (what to buy).
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromSmoothyGlobal(
SmoothyInfo memory smoothyInfo,
int128 fromTokenIdx,
int128 toTokenIdx
)
public
view
returns (uint256[] memory makerTokenAmounts)
{
makerTokenAmounts = this.sampleSellsFromSmoothy(
smoothyInfo,
fromTokenIdx,
toTokenIdx,
SAMPLE_VALUES
);
}
/// @dev Sample sell quotes from Smoothy.
/// @param smoothyInfo Smoothy information specific to this token pair.
/// @param fromTokenIdx Index of the taker token (what to sell).
@@ -98,6 +123,29 @@ contract SmoothySampler is
}
}
/// @dev Sample buy quotes from Smoothy.
/// @param smoothyInfo Smoothy information specific to this token pair.
/// @param fromTokenIdx Index of the taker token (what to sell).
/// @param toTokenIdx Index of the maker token (what to buy).
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromSmoothyGlobal(
SmoothyInfo memory smoothyInfo,
int128 fromTokenIdx,
int128 toTokenIdx
)
public
view
returns (uint256[] memory takerTokenAmounts)
{
takerTokenAmounts = _sampleBuysFromSmoothy(
smoothyInfo,
fromTokenIdx,
toTokenIdx,
SAMPLE_VALUES
);
}
/// @dev Sample buy quotes from Smoothy.
/// @param smoothyInfo Smoothy information specific to this token pair.
/// @param fromTokenIdx Index of the taker token (what to sell).
@@ -105,13 +153,13 @@ contract SmoothySampler is
/// @param makerTokenAmounts Maker token buy amount for each sample.
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromSmoothy(
function _sampleBuysFromSmoothy(
SmoothyInfo memory smoothyInfo,
int128 fromTokenIdx,
int128 toTokenIdx,
uint256[] memory makerTokenAmounts
)
public
internal
view
returns (uint256[] memory takerTokenAmounts)
{

View File

@@ -20,11 +20,14 @@
pragma solidity ^0.6;
pragma experimental ABIEncoderV2;
import "@0x/contracts-utils/contracts/src/v06/LibBytesV06.sol";
import "./LibBytes.sol";
import "./SamplerBase.sol";
contract TwoHopSampler {
using LibBytesV06 for bytes;
contract TwoHopSampler is
SamplerBase
{
using LibBytes for bytes;
struct HopInfo {
uint256 sourceIndex;
@@ -36,6 +39,7 @@ contract TwoHopSampler {
bytes[] memory secondHopCalls,
uint256 sellAmount
)
resetsSampleValues()
public
returns (
HopInfo memory firstHop,
@@ -44,8 +48,11 @@ contract TwoHopSampler {
)
{
uint256 intermediateAssetAmount = 0;
uint256[] memory tmpSampleValues = new uint256[](1);
for (uint256 i = 0; i != firstHopCalls.length; ++i) {
firstHopCalls[i].writeUint256(firstHopCalls[i].length - 32, sellAmount);
// Set the temporary global sample values
tmpSampleValues[0] = sellAmount;
SAMPLE_VALUES = tmpSampleValues;
(bool didSucceed, bytes memory returnData) = address(this).call(firstHopCalls[i]);
if (didSucceed) {
uint256 amount = returnData.readUint256(returnData.length - 32);
@@ -60,7 +67,9 @@ contract TwoHopSampler {
return (firstHop, secondHop, buyAmount);
}
for (uint256 j = 0; j != secondHopCalls.length; ++j) {
secondHopCalls[j].writeUint256(secondHopCalls[j].length - 32, intermediateAssetAmount);
// Set the temporary global sample values
tmpSampleValues[0] = intermediateAssetAmount;
SAMPLE_VALUES = tmpSampleValues;
(bool didSucceed, bytes memory returnData) = address(this).call(secondHopCalls[j]);
if (didSucceed) {
uint256 amount = returnData.readUint256(returnData.length - 32);
@@ -77,7 +86,8 @@ contract TwoHopSampler {
bytes[] memory firstHopCalls,
bytes[] memory secondHopCalls,
uint256 buyAmount
)
)
resetsSampleValues()
public
returns (
HopInfo memory firstHop,
@@ -87,8 +97,11 @@ contract TwoHopSampler {
{
sellAmount = uint256(-1);
uint256 intermediateAssetAmount = uint256(-1);
uint256[] memory tmpSampleValues = new uint256[](1);
for (uint256 j = 0; j != secondHopCalls.length; ++j) {
secondHopCalls[j].writeUint256(secondHopCalls[j].length - 32, buyAmount);
// Set the temporary global sample values
tmpSampleValues[0] = buyAmount;
SAMPLE_VALUES = tmpSampleValues;
(bool didSucceed, bytes memory returnData) = address(this).call(secondHopCalls[j]);
if (didSucceed) {
uint256 amount = returnData.readUint256(returnData.length - 32);
@@ -106,7 +119,9 @@ contract TwoHopSampler {
return (firstHop, secondHop, sellAmount);
}
for (uint256 i = 0; i != firstHopCalls.length; ++i) {
firstHopCalls[i].writeUint256(firstHopCalls[i].length - 32, intermediateAssetAmount);
// Set the temporary global sample values
tmpSampleValues[0] = intermediateAssetAmount;
SAMPLE_VALUES = tmpSampleValues;
(bool didSucceed, bytes memory returnData) = address(this).call(firstHopCalls[i]);
if (didSucceed) {
uint256 amount = returnData.readUint256(returnData.length - 32);

View File

@@ -22,6 +22,7 @@ pragma experimental ABIEncoderV2;
import "./interfaces/IUniswapExchangeQuotes.sol";
import "./SamplerUtils.sol";
import "./SamplerBase.sol";
interface IUniswapExchangeFactory {
@@ -36,11 +37,34 @@ interface IUniswapExchangeFactory {
contract UniswapSampler is
SamplerBase,
SamplerUtils
{
/// @dev Gas limit for Uniswap calls.
uint256 constant private UNISWAP_CALL_GAS = 150e3; // 150k
/// @dev Sample sell quotes from Uniswap.
/// @param router Address of the Uniswap Router
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromUniswapGlobal(
address router,
address takerToken,
address makerToken
)
public
view
returns (uint256[] memory makerTokenAmounts)
{
makerTokenAmounts = _sampleSellsFromUniswap(
router,
takerToken,
makerToken,
SAMPLE_VALUES
);
}
/// @dev Sample sell quotes from Uniswap.
/// @param router Address of the Uniswap Router
/// @param takerToken Address of the taker token (what to sell).
@@ -48,13 +72,13 @@ contract UniswapSampler is
/// @param takerTokenAmounts Taker token sell amount for each sample.
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromUniswap(
function _sampleSellsFromUniswap(
address router,
address takerToken,
address makerToken,
uint256[] memory takerTokenAmounts
)
public
internal
view
returns (uint256[] memory makerTokenAmounts)
{
@@ -104,19 +128,41 @@ contract UniswapSampler is
}
}
/// @dev Sample buy quotes from Uniswap.
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromUniswapGlobal(
address router,
address takerToken,
address makerToken
)
public
view
returns (uint256[] memory takerTokenAmounts)
{
takerTokenAmounts = _sampleBuysFromUniswap(
router,
takerToken,
makerToken,
SAMPLE_VALUES
);
}
/// @dev Sample buy quotes from Uniswap.
/// @param takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy).
/// @param makerTokenAmounts Maker token sell amount for each sample.
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromUniswap(
function _sampleBuysFromUniswap(
address router,
address takerToken,
address makerToken,
uint256[] memory makerTokenAmounts
)
public
internal
view
returns (uint256[] memory takerTokenAmounts)
{

View File

@@ -21,20 +21,42 @@ pragma solidity ^0.6;
pragma experimental ABIEncoderV2;
import "./interfaces/IUniswapV2Router01.sol";
import "./SamplerBase.sol";
contract UniswapV2Sampler
contract UniswapV2Sampler is
SamplerBase
{
/// @dev Gas limit for UniswapV2 calls.
uint256 constant private UNISWAPV2_CALL_GAS = 150e3; // 150k
/// @dev Sample sell quotes from UniswapV2.
/// @param router Router to look up tokens and amounts
/// @param path Token route. Should be takerToken -> makerToken
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromUniswapV2Global(
address router,
address[] memory path
)
public
view
returns (uint256[] memory makerTokenAmounts)
{
makerTokenAmounts = _sampleSellsFromUniswapV2(
router,
path,
SAMPLE_VALUES
);
}
/// @dev Sample sell quotes from UniswapV2.
/// @param router Router to look up tokens and amounts
/// @param path Token route. Should be takerToken -> makerToken
/// @param takerTokenAmounts Taker token sell amount for each sample.
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromUniswapV2(
function _sampleSellsFromUniswapV2(
address router,
address[] memory path,
uint256[] memory takerTokenAmounts
@@ -64,18 +86,38 @@ contract UniswapV2Sampler
}
}
/// @dev Sample buy quotes from UniswapV2.
/// @param router Router to look up tokens and amounts
/// @param path Token route. Should be takerToken -> makerToken.
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromUniswapV2Global(
address router,
address[] memory path
)
public
view
returns (uint256[] memory takerTokenAmounts)
{
takerTokenAmounts = _sampleBuysFromUniswapV2(
router,
path,
SAMPLE_VALUES
);
}
/// @dev Sample buy quotes from UniswapV2.
/// @param router Router to look up tokens and amounts
/// @param path Token route. Should be takerToken -> makerToken.
/// @param makerTokenAmounts Maker token buy amount for each sample.
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromUniswapV2(
function _sampleBuysFromUniswapV2(
address router,
address[] memory path,
uint256[] memory makerTokenAmounts
)
public
internal
view
returns (uint256[] memory takerTokenAmounts)
{

View File

@@ -20,7 +20,8 @@
pragma solidity ^0.6;
pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
import "./interfaces/IERC20TokenV06.sol";
import "./SamplerBase.sol";
interface IUniswapV3Quoter {
function factory()
@@ -48,11 +49,34 @@ interface IUniswapV3Pool {
function fee() external view returns (uint24);
}
contract UniswapV3Sampler
contract UniswapV3Sampler is
SamplerBase
{
/// @dev Gas limit for UniswapV3 calls. This is 100% a guess.
uint256 constant private QUOTE_GAS = 600e3;
/// @dev Sample sell quotes from UniswapV3.
/// @param quoter UniswapV3 Quoter contract.
/// @param path Token route. Should be takerToken -> makerToken
/// @return uniswapPaths The encoded uniswap path for each sample.
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromUniswapV3Global(
IUniswapV3Quoter quoter,
IERC20TokenV06[] memory path
)
public
returns (
bytes[] memory uniswapPaths,
uint256[] memory makerTokenAmounts
)
{
(uniswapPaths, makerTokenAmounts) = _sampleSellsFromUniswapV3(
quoter,
path,
SAMPLE_VALUES
);
}
/// @dev Sample sell quotes from UniswapV3.
/// @param quoter UniswapV3 Quoter contract.
/// @param path Token route. Should be takerToken -> makerToken
@@ -60,12 +84,12 @@ contract UniswapV3Sampler
/// @return uniswapPaths The encoded uniswap path for each sample.
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromUniswapV3(
function _sampleSellsFromUniswapV3(
IUniswapV3Quoter quoter,
IERC20TokenV06[] memory path,
uint256[] memory takerTokenAmounts
)
public
internal
returns (
bytes[] memory uniswapPaths,
uint256[] memory makerTokenAmounts
@@ -104,6 +128,29 @@ contract UniswapV3Sampler
}
}
/// @dev Sample buy quotes from UniswapV3.
/// @param quoter UniswapV3 Quoter contract.
/// @param path Token route. Should be takerToken -> makerToken.
/// @return uniswapPaths The encoded uniswap path for each sample.
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromUniswapV3Global(
IUniswapV3Quoter quoter,
IERC20TokenV06[] memory path
)
public
returns (
bytes[] memory uniswapPaths,
uint256[] memory takerTokenAmounts
)
{
(uniswapPaths, takerTokenAmounts) = _sampleBuysFromUniswapV3(
quoter,
path,
SAMPLE_VALUES
);
}
/// @dev Sample buy quotes from UniswapV3.
/// @param quoter UniswapV3 Quoter contract.
/// @param path Token route. Should be takerToken -> makerToken.
@@ -111,12 +158,12 @@ contract UniswapV3Sampler
/// @return uniswapPaths The encoded uniswap path for each sample.
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromUniswapV3(
function _sampleBuysFromUniswapV3(
IUniswapV3Quoter quoter,
IERC20TokenV06[] memory path,
uint256[] memory makerTokenAmounts
)
public
internal
returns (
bytes[] memory uniswapPaths,
uint256[] memory takerTokenAmounts

View File

@@ -21,12 +21,10 @@
pragma solidity ^0.6;
pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
import "./interfaces/IERC20TokenV06.sol";
contract UtilitySampler {
using LibERC20TokenV06 for IERC20TokenV06;
IERC20TokenV06 private immutable UTILITY_ETH_ADDRESS = IERC20TokenV06(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);
function getTokenDecimals(IERC20TokenV06[] memory tokens)
@@ -38,7 +36,7 @@ contract UtilitySampler {
for (uint256 i = 0; i != tokens.length; i++) {
decimals[i] = tokens[i] == UTILITY_ETH_ADDRESS
? 18
: tokens[i].compatDecimals();
: tokens[i].decimals();
}
}
@@ -51,7 +49,7 @@ contract UtilitySampler {
for (uint256 i = 0; i != tokens.length; i++) {
balances[i] = tokens[i] == UTILITY_ETH_ADDRESS
? account.balance
: tokens[i].compatBalanceOf(account);
: tokens[i].balanceOf(account);
}
}
@@ -64,7 +62,7 @@ contract UtilitySampler {
for (uint256 i = 0; i != tokens.length; i++) {
allowances[i] = tokens[i] == UTILITY_ETH_ADDRESS
? 0
: tokens[i].compatAllowance(account, spender);
: tokens[i].allowance(account, spender);
}
}

View File

@@ -0,0 +1,96 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2022 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.6.5;
interface IERC20TokenV06 {
// solhint-disable no-simple-event-func-name
event Transfer(
address indexed from,
address indexed to,
uint256 value
);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
/// @dev send `value` token to `to` from `msg.sender`
/// @param to The address of the recipient
/// @param value The amount of token to be transferred
/// @return True if transfer was successful
function transfer(address to, uint256 value)
external
returns (bool);
/// @dev send `value` token to `to` from `from` on the condition it is approved by `from`
/// @param from The address of the sender
/// @param to The address of the recipient
/// @param value The amount of token to be transferred
/// @return True if transfer was successful
function transferFrom(
address from,
address to,
uint256 value
)
external
returns (bool);
/// @dev `msg.sender` approves `spender` to spend `value` tokens
/// @param spender The address of the account able to transfer the tokens
/// @param value The amount of wei to be approved for transfer
/// @return Always true if the call has enough gas to complete execution
function approve(address spender, uint256 value)
external
returns (bool);
/// @dev Query total supply of token
/// @return Total supply of token
function totalSupply()
external
view
returns (uint256);
/// @dev Get the balance of `owner`.
/// @param owner The address from which the balance will be retrieved
/// @return Balance of owner
function balanceOf(address owner)
external
view
returns (uint256);
/// @dev Get the allowance for `spender` to spend from `owner`.
/// @param owner The address of the account owning tokens
/// @param spender The address of the account able to transfer the tokens
/// @return Amount of remaining tokens allowed to spent
function allowance(address owner, address spender)
external
view
returns (uint256);
/// @dev Get the number of decimals this token has.
function decimals()
external
view
returns (uint8);
}

View File

@@ -0,0 +1,118 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2022 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.6.5;
import "./IERC20TokenV06.sol";
interface ILiquidityProvider {
/// @dev An optional event an LP can emit for each fill against a source.
/// @param inputToken The input token.
/// @param outputToken The output token.
/// @param inputTokenAmount How much input token was sold.
/// @param outputTokenAmount How much output token was bought.
/// @param sourceId A bytes32 encoded ascii source ID. E.g., `bytes32('Curve')`/
/// @param sourceAddress An optional address associated with the source (e.g, a curve pool).
/// @param sourceId A bytes32 encoded ascii source ID. E.g., `bytes32('Curve')`/
/// @param sourceAddress An optional address associated with the source (e.g, a curve pool).
/// @param sender The caller of the LP.
/// @param recipient The recipient of the output tokens.
event LiquidityProviderFill(
IERC20TokenV06 inputToken,
IERC20TokenV06 outputToken,
uint256 inputTokenAmount,
uint256 outputTokenAmount,
bytes32 sourceId,
address sourceAddress,
address sender,
address recipient
);
/// @dev Trades `inputToken` for `outputToken`. The amount of `inputToken`
/// to sell must be transferred to the contract prior to calling this
/// function to trigger the trade.
/// @param inputToken The token being sold.
/// @param outputToken The token being bought.
/// @param recipient The recipient of the bought tokens.
/// @param minBuyAmount The minimum acceptable amount of `outputToken` to buy.
/// @param auxiliaryData Arbitrary auxiliary data supplied to the contract.
/// @return boughtAmount The amount of `outputToken` bought.
function sellTokenForToken(
IERC20TokenV06 inputToken,
IERC20TokenV06 outputToken,
address recipient,
uint256 minBuyAmount,
bytes calldata auxiliaryData
)
external
returns (uint256 boughtAmount);
/// @dev Trades ETH for token. ETH must either be attached to this function
/// call or sent to the contract prior to calling this function to
/// trigger the trade.
/// @param outputToken The token being bought.
/// @param recipient The recipient of the bought tokens.
/// @param minBuyAmount The minimum acceptable amount of `outputToken` to buy.
/// @param auxiliaryData Arbitrary auxiliary data supplied to the contract.
/// @return boughtAmount The amount of `outputToken` bought.
function sellEthForToken(
IERC20TokenV06 outputToken,
address recipient,
uint256 minBuyAmount,
bytes calldata auxiliaryData
)
external
payable
returns (uint256 boughtAmount);
/// @dev Trades token for ETH. The token must be sent to the contract prior
/// to calling this function to trigger the trade.
/// @param inputToken The token being sold.
/// @param recipient The recipient of the bought tokens.
/// @param minBuyAmount The minimum acceptable amount of ETH to buy.
/// @param auxiliaryData Arbitrary auxiliary data supplied to the contract.
/// @return boughtAmount The amount of ETH bought.
function sellTokenForEth(
IERC20TokenV06 inputToken,
address payable recipient,
uint256 minBuyAmount,
bytes calldata auxiliaryData
)
external
returns (uint256 boughtAmount);
/// @dev Quotes the amount of `outputToken` that would be obtained by
/// selling `sellAmount` of `inputToken`.
/// @param inputToken Address of the taker token (what to sell). Use
/// the wETH address if selling ETH.
/// @param outputToken Address of the maker token (what to buy). Use
/// the wETH address if buying ETH.
/// @param sellAmount Amount of `inputToken` to sell.
/// @return outputTokenAmount Amount of `outputToken` that would be obtained.
function getSellQuote(
IERC20TokenV06 inputToken,
IERC20TokenV06 outputToken,
uint256 sellAmount
)
external
view
returns (uint256 outputTokenAmount);
}

View File

@@ -0,0 +1,56 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.6;
pragma experimental ABIEncoderV2;
import "./TestBase.sol";
import "../src/ERC20BridgeSampler.sol";
contract CurveSamplerTest is
TestBase
{
ERC20BridgeSampler sampler;
function setUp() public {
sampler = new ERC20BridgeSampler();
sampler.setSampleValues(_toSingleValueArray(1e18));
}
function testCurveSampler()
public
skip()
requiresChainId(1)
requiresBlockNumberGte(14000000)
{
uint256[] memory values = sampler.sampleSellsFromCurveGlobal(
CurveSampler.CurveInfo({
poolAddress: 0x06cb22615BA53E60D67Bf6C341a0fD5E718E1655,
sellQuoteFunctionSelector: 0x07211ef7,
buyQuoteFunctionSelector: 0x00000000
}),
0,
1
);
assertGt(values[0], 0);
}
function testCurveSamplerOptimism()
public
requiresChainId(10)
logs_gas()
{
uint256[] memory values = sampler.sampleSellsFromCurveGlobal(
CurveSampler.CurveInfo({
poolAddress: 0x1337BedC9D22ecbe766dF105c9623922A27963EC,
sellQuoteFunctionSelector: 0x5e0d443f,
buyQuoteFunctionSelector: 0x00000000
}),
0,
1
);
assertGt(values[0], 0);
}
}

View File

@@ -0,0 +1,435 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
pragma solidity ^0.6;
contract DSTest {
event log (string str);
event logs (bytes data);
event log_address (address addr);
event log_bytes32 (bytes32 data);
event log_int (int data);
event log_uint (uint data);
event log_bytes (bytes data);
event log_string (string str);
event log_named_address (string key, address val);
event log_named_bytes32 (string key, bytes32 val);
event log_named_decimal_int (string key, int val, uint decimals);
event log_named_decimal_uint (string key, uint val, uint decimals);
event log_named_int (string key, int val);
event log_named_uint (string key, uint val);
event log_named_bytes (string key, bytes val);
event log_named_string (string key, string val);
event log_named_expected_uints (string key, uint expected, uint actual);
bool public IS_TEST = true;
bool public failed;
address constant HEVM_ADDRESS =
address(bytes20(uint160(uint256(keccak256('hevm cheat code')))));
modifier mayRevert() { _; }
modifier testopts(string memory) { _; }
function fail() internal {
failed = true;
}
modifier logs_gas() {
uint startGas = gasleft();
_;
uint endGas = gasleft();
emit log_named_uint("gas", startGas - endGas);
}
function assertTrue(bool condition) internal {
if (!condition) {
emit log("Error: Assertion Failed");
fail();
}
}
function assertTrue(bool condition, string memory err) internal {
if (!condition) {
emit log_named_string("Error", err);
assertTrue(condition);
}
}
function assertEq(address a, address b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [address]");
emit log_named_address(" Expected", b);
emit log_named_address(" Actual", a);
fail();
}
}
function assertEq(address a, address b, string memory err) internal {
if (a != b) {
emit log_named_string ("Error", err);
assertEq(a, b);
}
}
function assertEq(bytes32 a, bytes32 b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [bytes32]");
emit log_named_bytes32(" Expected", b);
emit log_named_bytes32(" Actual", a);
fail();
}
}
function assertEq(bytes32 a, bytes32 b, string memory err) internal {
if (a != b) {
emit log_named_string ("Error", err);
assertEq(a, b);
}
}
function assertEq32(bytes32 a, bytes32 b) internal {
assertEq(a, b);
}
function assertEq32(bytes32 a, bytes32 b, string memory err) internal {
assertEq(a, b, err);
}
function assertEq(int a, int b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [int]");
emit log_named_int(" Expected", b);
emit log_named_int(" Actual", a);
fail();
}
}
function assertEq(int a, int b, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function assertEq(uint a, uint b) internal {
if (a != b) {
emit log("Error: a == b not satisfied [uint]");
emit log_named_uint(" Expected", b);
emit log_named_uint(" Actual", a);
fail();
}
}
function assertEq(uint a, uint b, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function assertEqDecimal(int a, int b, uint decimals) internal {
if (a != b) {
emit log("Error: a == b not satisfied [decimal int]");
emit log_named_decimal_int(" Expected", b, decimals);
emit log_named_decimal_int(" Actual", a, decimals);
fail();
}
}
function assertEqDecimal(int a, int b, uint decimals, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEqDecimal(a, b, decimals);
}
}
function assertEqDecimal(uint a, uint b, uint decimals) internal {
if (a != b) {
emit log("Error: a == b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Expected", b, decimals);
emit log_named_decimal_uint(" Actual", a, decimals);
fail();
}
}
function assertEqDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a != b) {
emit log_named_string("Error", err);
assertEqDecimal(a, b, decimals);
}
}
function assertGt(uint a, uint b) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertGt(uint a, uint b, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGt(a, b);
}
}
function assertGt(int a, int b) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertGt(int a, int b, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGt(a, b);
}
}
function assertGtDecimal(int a, int b, uint decimals) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertGtDecimal(int a, int b, uint decimals, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGtDecimal(a, b, decimals);
}
}
function assertGtDecimal(uint a, uint b, uint decimals) internal {
if (a <= b) {
emit log("Error: a > b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertGtDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a <= b) {
emit log_named_string("Error", err);
assertGtDecimal(a, b, decimals);
}
}
function assertGe(uint a, uint b) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertGe(uint a, uint b, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGe(a, b);
}
}
function assertGe(int a, int b) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertGe(int a, int b, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGe(a, b);
}
}
function assertGeDecimal(int a, int b, uint decimals) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertGeDecimal(int a, int b, uint decimals, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertGeDecimal(uint a, uint b, uint decimals) internal {
if (a < b) {
emit log("Error: a >= b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertGeDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a < b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertLt(uint a, uint b) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertLt(uint a, uint b, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLt(a, b);
}
}
function assertLt(int a, int b) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertLt(int a, int b, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLt(a, b);
}
}
function assertLtDecimal(int a, int b, uint decimals) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertLtDecimal(int a, int b, uint decimals, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLtDecimal(a, b, decimals);
}
}
function assertLtDecimal(uint a, uint b, uint decimals) internal {
if (a >= b) {
emit log("Error: a < b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertLtDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a >= b) {
emit log_named_string("Error", err);
assertLtDecimal(a, b, decimals);
}
}
function assertLe(uint a, uint b) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [uint]");
emit log_named_uint(" Value a", a);
emit log_named_uint(" Value b", b);
fail();
}
}
function assertLe(uint a, uint b, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLe(a, b);
}
}
function assertLe(int a, int b) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [int]");
emit log_named_int(" Value a", a);
emit log_named_int(" Value b", b);
fail();
}
}
function assertLe(int a, int b, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLe(a, b);
}
}
function assertLeDecimal(int a, int b, uint decimals) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [decimal int]");
emit log_named_decimal_int(" Value a", a, decimals);
emit log_named_decimal_int(" Value b", b, decimals);
fail();
}
}
function assertLeDecimal(int a, int b, uint decimals, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertLeDecimal(a, b, decimals);
}
}
function assertLeDecimal(uint a, uint b, uint decimals) internal {
if (a > b) {
emit log("Error: a <= b not satisfied [decimal uint]");
emit log_named_decimal_uint(" Value a", a, decimals);
emit log_named_decimal_uint(" Value b", b, decimals);
fail();
}
}
function assertLeDecimal(uint a, uint b, uint decimals, string memory err) internal {
if (a > b) {
emit log_named_string("Error", err);
assertGeDecimal(a, b, decimals);
}
}
function assertEq(string memory a, string memory b) internal {
if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {
emit log("Error: a == b not satisfied [string]");
emit log_named_string(" Value a", a);
emit log_named_string(" Value b", b);
fail();
}
}
function assertEq(string memory a, string memory b, string memory err) internal {
if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) {
emit log_named_string("Error", err);
assertEq(a, b);
}
}
function checkEq0(bytes memory a, bytes memory b) internal pure returns (bool ok) {
ok = true;
if (a.length == b.length) {
for (uint i = 0; i < a.length; i++) {
if (a[i] != b[i]) {
ok = false;
}
}
} else {
ok = false;
}
}
function assertEq0(bytes memory a, bytes memory b) internal {
if (!checkEq0(a, b)) {
emit log("Error: a == b not satisfied [bytes]");
emit log_named_bytes(" Expected", a);
emit log_named_bytes(" Actual", b);
fail();
}
}
function assertEq0(bytes memory a, bytes memory b, string memory err) internal {
if (!checkEq0(a, b)) {
emit log_named_string("Error", err);
assertEq0(a, b);
}
}
}

View File

@@ -36,4 +36,4 @@ contract DummyLiquidityProvider
{
takerTokenAmount = buyAmount + 1;
}
}
}

View File

@@ -0,0 +1,57 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.6;
import "./DSTest.sol";
contract TestBase is
DSTest
{
function _toSingleValueArray(uint256 v)
internal
pure
returns (uint256[] memory arr)
{
arr = new uint256[](1);
arr[0] = v;
}
modifier requiresChainId(uint256 chainId)
{
if (chainId != _chainId())
{
emit log_named_expected_uints("skip: wrong chain id", chainId, _chainId());
return;
}
_;
}
modifier requiresBlockNumberGte(uint256 blockNumber)
{
if (block.number < blockNumber)
{
emit log_named_expected_uints("skip: block.number < blockNumber", blockNumber, block.number);
return;
}
_;
}
modifier skip()
{
if (true) {
emit log_string("skip");
return;
}
_;
}
function _chainId()
internal
returns (uint256 id)
{
uint256 id;
assembly {
id := chainid()
}
return id;
}
}

View File

@@ -452,4 +452,4 @@ contract TestERC20BridgeSampler is
{
return LibDeterministicQuotes.getDeterministicTokenDecimals(tokenAddress);
}
}
}

View File

@@ -96,7 +96,7 @@ contract TestNativeOrderSampler is
orderInfo.takerTokenFilledAmount = uint128(order.expiry);
// Calculate how much is fillable in maker terms given the filled taker amount
uint256 fillableMakerTokenAmount = LibMathV06.getPartialAmountFloor(
uint256 fillableMakerTokenAmount = LibSafeMath.getPartialAmountFloor(
uint256(
order.takerAmount
- orderInfo.takerTokenFilledAmount
@@ -106,13 +106,13 @@ contract TestNativeOrderSampler is
);
// Take the min of the balance/allowance and the fillable maker amount
fillableMakerTokenAmount = LibSafeMathV06.min256(
fillableMakerTokenAmount = LibSafeMath.min256(
fillableMakerTokenAmount,
_getSpendableERC20BalanceOf(order.makerToken, order.maker)
);
// Convert to taker terms
actualFillableTakerTokenAmount = LibMathV06.getPartialAmountCeil(
actualFillableTakerTokenAmount = LibSafeMath.getPartialAmountCeil(
fillableMakerTokenAmount,
uint256(order.makerAmount),
uint256(order.takerAmount)
@@ -127,7 +127,7 @@ contract TestNativeOrderSampler is
view
returns (uint256)
{
return LibSafeMathV06.min256(
return LibSafeMath.min256(
token.allowance(owner, address(this)),
token.balanceOf(owner)
);

File diff suppressed because one or more lines are too long

View File

@@ -39,7 +39,7 @@
"config": {
"publicInterfaceContracts": "ERC20BridgeSampler,BalanceChecker,FakeTaker",
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
"abis": "./test/generated-artifacts/@(ApproximateBuys|BalanceChecker|BalancerSampler|BalancerV2Sampler|BancorSampler|CompoundSampler|CurveSampler|DODOSampler|DODOV2Sampler|DummyLiquidityProvider|ERC20BridgeSampler|FakeTaker|IBalancer|IBancor|ICurve|IKyberNetwork|IMStable|IMooniswap|IMultiBridge|IShell|ISmoothy|IUniswapExchangeQuotes|IUniswapV2Router01|KyberDmmSampler|KyberSampler|LidoSampler|LiquidityProviderSampler|MStableSampler|MakerPSMSampler|MooniswapSampler|MultiBridgeSampler|NativeOrderSampler|SamplerUtils|ShellSampler|SmoothySampler|TestERC20BridgeSampler|TestNativeOrderSampler|TwoHopSampler|UniswapSampler|UniswapV2Sampler|UniswapV3Sampler|UtilitySampler).json",
"abis": "./test/generated-artifacts/@(ApproximateBuys|BalanceChecker|BalancerSampler|BalancerV2Sampler|BancorSampler|CompoundSampler|CurveSampler|CurveSamplerTest|DODOSampler|DODOV2Sampler|DSTest|DummyLiquidityProvider|ERC20BridgeSampler|FakeTaker|IBalancer|IBancor|ICurve|IERC20TokenV06|IKyberNetwork|ILiquidityProvider|IMStable|IMooniswap|IMultiBridge|IShell|ISmoothy|IUniswapExchangeQuotes|IUniswapV2Router01|KyberDmmSampler|KyberSampler|LibBytes|LibSafeMath|LidoSampler|LiquidityProviderSampler|MStableSampler|MakerPSMSampler|MooniswapSampler|MultiBridgeSampler|NativeOrderSampler|SamplerBase|SamplerUtils|ShellSampler|SmoothySampler|TestBase|TestERC20BridgeSampler|TestNativeOrderSampler|TwoHopSampler|UniswapSampler|UniswapV2Sampler|UniswapV2SamplerTest|UniswapV3Sampler|UtilitySampler).json",
"postpublish": {
"assets": []
}

View File

@@ -164,6 +164,8 @@ export class MarketOperationUtils {
// Get native order fillable amounts.
this._sampler.getLimitOrderFillableTakerAmounts(nativeOrders, this.contractAddresses.exchangeProxy),
// Get ETH -> maker token price.
// Set the global sample value to discover the network fee token in maker token
this._sampler.setSampleValues([this._nativeFeeTokenAmount]),
this._sampler.getMedianSellRate(
feeSourceFilters.sources,
makerToken,
@@ -171,6 +173,7 @@ export class MarketOperationUtils {
this._nativeFeeTokenAmount,
),
// Get ETH -> taker token price.
// Set the global sample value to discover the network fee token in taker token
this._sampler.getMedianSellRate(
feeSourceFilters.sources,
takerToken,
@@ -178,7 +181,11 @@ export class MarketOperationUtils {
this._nativeFeeTokenAmount,
),
// Get sell quotes for taker -> maker.
// Set the global sample values to the increasing sized samples up to takerAmount
this._sampler.setSampleValues(sampleAmounts),
this._sampler.getSellQuotes(quoteSourceFilters.sources, makerToken, takerToken, sampleAmounts),
// Set the global sample values to just the entire amount for MultiHop
this._sampler.setSampleValues([takerAmount]),
this._sampler.getTwoHopSellQuotes(
quoteSourceFilters.isAllowed(ERC20BridgeSource.MultiHop) ? quoteSourceFilters.sources : [],
makerToken,
@@ -198,9 +205,12 @@ export class MarketOperationUtils {
gasBefore,
tokenDecimals,
orderFillableTakerAmounts,
_setFeeTokenSample,
outputAmountPerEth,
inputAmountPerEth,
_setSampleValues,
dexQuotes,
_setMultiHopSample,
rawTwoHopQuotes,
isTxOriginContract,
gasAfter,

View File

@@ -162,6 +162,25 @@ export class DexOrderSampler extends SamplerOperations {
BatchedOperationResult<T10>,
]>;
// prettier-ignore
public async executeAsync<
T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13
>(...ops: [T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]): Promise<[
BatchedOperationResult<T1>,
BatchedOperationResult<T2>,
BatchedOperationResult<T3>,
BatchedOperationResult<T4>,
BatchedOperationResult<T5>,
BatchedOperationResult<T6>,
BatchedOperationResult<T7>,
BatchedOperationResult<T8>,
BatchedOperationResult<T9>,
BatchedOperationResult<T10>,
BatchedOperationResult<T11>,
BatchedOperationResult<T12>,
BatchedOperationResult<T13>,
]>;
/**
* Run a series of operations from `DexOrderSampler.ops` in a single transaction.
*/

View File

@@ -182,6 +182,17 @@ export class SamplerOperations {
};
}
public setSampleValues(sampleValues: BigNumber[]): BatchedOperation<boolean> {
return {
encodeCall: () => this._samplerContract.setSampleValues(sampleValues).getABIEncodedTransactionData(),
handleCallResults: (_callResults: string) => true,
handleRevert: () => {
/* should never happen */
throw new Error('Invalid result for setting sample values');
},
};
}
public getGasLeft(): BatchedOperation<BigNumber> {
return {
encodeCall: () => this._samplerContract.getGasLeft().getABIEncodedTransactionData(),
@@ -251,17 +262,17 @@ export class SamplerOperations {
reserveOffset: BigNumber,
makerToken: string,
takerToken: string,
takerFillAmounts: BigNumber[],
_takerFillAmounts: BigNumber[],
): SourceQuoteOperation {
return new SamplerContractOperation({
source: ERC20BridgeSource.Kyber,
contract: this._samplerContract,
function: this._samplerContract.sampleSellsFromKyberNetwork,
params: [{ ...kyberOpts, reserveOffset, hint: NULL_BYTES }, takerToken, makerToken, takerFillAmounts],
function: this._samplerContract.sampleSellsFromKyberNetworkGlobal,
params: [{ ...kyberOpts, reserveOffset, hint: NULL_BYTES }, takerToken, makerToken],
callback: (callResults: string, fillData: KyberFillData): BigNumber[] => {
const [reserveId, hint, samples] = this._samplerContract.getABIDecodedReturnData<
[string, string, BigNumber[]]
>('sampleSellsFromKyberNetwork', callResults);
>('sampleSellsFromKyberNetworkGlobal', callResults);
fillData.hint = hint;
fillData.reserveId = reserveId;
fillData.networkProxy = kyberOpts.networkProxy;
@@ -275,17 +286,17 @@ export class SamplerOperations {
reserveOffset: BigNumber,
makerToken: string,
takerToken: string,
makerFillAmounts: BigNumber[],
_makerFillAmounts: BigNumber[],
): SourceQuoteOperation {
return new SamplerContractOperation({
source: ERC20BridgeSource.Kyber,
contract: this._samplerContract,
function: this._samplerContract.sampleBuysFromKyberNetwork,
params: [{ ...kyberOpts, reserveOffset, hint: NULL_BYTES }, takerToken, makerToken, makerFillAmounts],
function: this._samplerContract.sampleBuysFromKyberNetworkGlobal,
params: [{ ...kyberOpts, reserveOffset, hint: NULL_BYTES }, takerToken, makerToken],
callback: (callResults: string, fillData: KyberFillData): BigNumber[] => {
const [reserveId, hint, samples] = this._samplerContract.getABIDecodedReturnData<
[string, string, BigNumber[]]
>('sampleBuysFromKyberNetwork', callResults);
>('sampleBuysFromKyberNetworkGlobal', callResults);
fillData.hint = hint;
fillData.reserveId = reserveId;
fillData.networkProxy = kyberOpts.networkProxy;
@@ -297,16 +308,16 @@ export class SamplerOperations {
public getKyberDmmSellQuotes(
router: string,
tokenAddressPath: string[],
takerFillAmounts: BigNumber[],
_takerFillAmounts: BigNumber[],
): SourceQuoteOperation<KyberDmmFillData> {
return new SamplerContractOperation({
source: ERC20BridgeSource.KyberDmm,
contract: this._samplerContract,
function: this._samplerContract.sampleSellsFromKyberDmm,
params: [router, tokenAddressPath, takerFillAmounts],
function: this._samplerContract.sampleSellsFromKyberDmmGlobal,
params: [router, tokenAddressPath],
callback: (callResults: string, fillData: KyberDmmFillData): BigNumber[] => {
const [pools, samples] = this._samplerContract.getABIDecodedReturnData<[string[], BigNumber[]]>(
'sampleSellsFromKyberDmm',
'sampleSellsFromKyberDmmGlobal',
callResults,
);
fillData.poolsPath = pools;
@@ -320,16 +331,16 @@ export class SamplerOperations {
public getKyberDmmBuyQuotes(
router: string,
tokenAddressPath: string[],
makerFillAmounts: BigNumber[],
_makerFillAmounts: BigNumber[],
): SourceQuoteOperation<KyberDmmFillData> {
return new SamplerContractOperation({
source: ERC20BridgeSource.KyberDmm,
contract: this._samplerContract,
function: this._samplerContract.sampleBuysFromKyberDmm,
params: [router, tokenAddressPath, makerFillAmounts],
function: this._samplerContract.sampleBuysFromKyberDmmGlobal,
params: [router, tokenAddressPath],
callback: (callResults: string, fillData: KyberDmmFillData): BigNumber[] => {
const [pools, samples] = this._samplerContract.getABIDecodedReturnData<[string[], BigNumber[]]>(
'sampleBuysFromKyberDmm',
'sampleBuysFromKyberDmmGlobal',
callResults,
);
fillData.poolsPath = pools;
@@ -353,8 +364,8 @@ export class SamplerOperations {
source: ERC20BridgeSource.Uniswap,
fillData: { router },
contract: this._samplerContract,
function: this._samplerContract.sampleSellsFromUniswap,
params: [router, uniswapTakerToken, uniswapMakerToken, takerFillAmounts],
function: this._samplerContract.sampleSellsFromUniswapGlobal,
params: [router, uniswapTakerToken, uniswapMakerToken],
});
}
@@ -362,7 +373,7 @@ export class SamplerOperations {
router: string,
makerToken: string,
takerToken: string,
makerFillAmounts: BigNumber[],
_makerFillAmounts: BigNumber[],
): SourceQuoteOperation<GenericRouterFillData> {
// Uniswap uses ETH instead of WETH, represented by address(0)
const uniswapTakerToken = takerToken === NATIVE_FEE_TOKEN_BY_CHAIN_ID[this.chainId] ? NULL_ADDRESS : takerToken;
@@ -371,38 +382,38 @@ export class SamplerOperations {
source: ERC20BridgeSource.Uniswap,
fillData: { router },
contract: this._samplerContract,
function: this._samplerContract.sampleBuysFromUniswap,
params: [router, uniswapTakerToken, uniswapMakerToken, makerFillAmounts],
function: this._samplerContract.sampleBuysFromUniswapGlobal,
params: [router, uniswapTakerToken, uniswapMakerToken],
});
}
public getUniswapV2SellQuotes(
router: string,
tokenAddressPath: string[],
takerFillAmounts: BigNumber[],
_takerFillAmounts: BigNumber[],
source: ERC20BridgeSource = ERC20BridgeSource.UniswapV2,
): SourceQuoteOperation<UniswapV2FillData> {
return new SamplerContractOperation({
source,
fillData: { tokenAddressPath, router },
contract: this._samplerContract,
function: this._samplerContract.sampleSellsFromUniswapV2,
params: [router, tokenAddressPath, takerFillAmounts],
function: this._samplerContract.sampleSellsFromUniswapV2Global,
params: [router, tokenAddressPath],
});
}
public getUniswapV2BuyQuotes(
router: string,
tokenAddressPath: string[],
makerFillAmounts: BigNumber[],
_makerFillAmounts: BigNumber[],
source: ERC20BridgeSource = ERC20BridgeSource.UniswapV2,
): SourceQuoteOperation<UniswapV2FillData> {
return new SamplerContractOperation({
source,
fillData: { tokenAddressPath, router },
contract: this._samplerContract,
function: this._samplerContract.sampleBuysFromUniswapV2,
params: [router, tokenAddressPath, makerFillAmounts],
function: this._samplerContract.sampleBuysFromUniswapV2Global,
params: [router, tokenAddressPath],
});
}
@@ -410,7 +421,7 @@ export class SamplerOperations {
providerAddress: string,
makerToken: string,
takerToken: string,
takerFillAmounts: BigNumber[],
_takerFillAmounts: BigNumber[],
gasCost: number,
source: ERC20BridgeSource = ERC20BridgeSource.LiquidityProvider,
): SourceQuoteOperation<LiquidityProviderFillData> {
@@ -421,8 +432,8 @@ export class SamplerOperations {
gasCost,
},
contract: this._samplerContract,
function: this._samplerContract.sampleSellsFromLiquidityProvider,
params: [providerAddress, takerToken, makerToken, takerFillAmounts],
function: this._samplerContract.sampleSellsFromLiquidityProviderGlobal,
params: [providerAddress, takerToken, makerToken],
});
}
@@ -430,7 +441,7 @@ export class SamplerOperations {
providerAddress: string,
makerToken: string,
takerToken: string,
makerFillAmounts: BigNumber[],
_makerFillAmounts: BigNumber[],
gasCost: number,
source: ERC20BridgeSource = ERC20BridgeSource.LiquidityProvider,
): SourceQuoteOperation<LiquidityProviderFillData> {
@@ -441,8 +452,8 @@ export class SamplerOperations {
gasCost,
},
contract: this._samplerContract,
function: this._samplerContract.sampleBuysFromLiquidityProvider,
params: [providerAddress, takerToken, makerToken, makerFillAmounts],
function: this._samplerContract.sampleBuysFromLiquidityProviderGlobal,
params: [providerAddress, takerToken, makerToken],
});
}
@@ -450,7 +461,7 @@ export class SamplerOperations {
pool: CurveInfo,
fromTokenIdx: number,
toTokenIdx: number,
takerFillAmounts: BigNumber[],
_takerFillAmounts: BigNumber[],
source: ERC20BridgeSource = ERC20BridgeSource.Curve,
): SourceQuoteOperation<CurveFillData> {
return new SamplerContractOperation({
@@ -461,7 +472,7 @@ export class SamplerOperations {
toTokenIdx,
},
contract: this._samplerContract,
function: this._samplerContract.sampleSellsFromCurve,
function: this._samplerContract.sampleSellsFromCurveGlobal,
params: [
{
poolAddress: pool.poolAddress,
@@ -470,7 +481,6 @@ export class SamplerOperations {
},
new BigNumber(fromTokenIdx),
new BigNumber(toTokenIdx),
takerFillAmounts,
],
});
}
@@ -479,7 +489,7 @@ export class SamplerOperations {
pool: CurveInfo,
fromTokenIdx: number,
toTokenIdx: number,
makerFillAmounts: BigNumber[],
_makerFillAmounts: BigNumber[],
source: ERC20BridgeSource = ERC20BridgeSource.Curve,
): SourceQuoteOperation<CurveFillData> {
return new SamplerContractOperation({
@@ -490,7 +500,7 @@ export class SamplerOperations {
toTokenIdx,
},
contract: this._samplerContract,
function: this._samplerContract.sampleBuysFromCurve,
function: this._samplerContract.sampleBuysFromCurveGlobal,
params: [
{
poolAddress: pool.poolAddress,
@@ -499,7 +509,6 @@ export class SamplerOperations {
},
new BigNumber(fromTokenIdx),
new BigNumber(toTokenIdx),
makerFillAmounts,
],
});
}
@@ -508,7 +517,7 @@ export class SamplerOperations {
pool: CurveInfo,
fromTokenIdx: number,
toTokenIdx: number,
takerFillAmounts: BigNumber[],
_takerFillAmounts: BigNumber[],
): SourceQuoteOperation<CurveFillData> {
return new SamplerContractOperation({
source: ERC20BridgeSource.Smoothy,
@@ -518,7 +527,7 @@ export class SamplerOperations {
toTokenIdx,
},
contract: this._samplerContract,
function: this._samplerContract.sampleSellsFromSmoothy,
function: this._samplerContract.sampleSellsFromSmoothyGlobal,
params: [
{
poolAddress: pool.poolAddress,
@@ -527,7 +536,6 @@ export class SamplerOperations {
},
new BigNumber(fromTokenIdx),
new BigNumber(toTokenIdx),
takerFillAmounts,
],
});
}
@@ -536,7 +544,7 @@ export class SamplerOperations {
pool: CurveInfo,
fromTokenIdx: number,
toTokenIdx: number,
makerFillAmounts: BigNumber[],
_makerFillAmounts: BigNumber[],
): SourceQuoteOperation<CurveFillData> {
return new SamplerContractOperation({
source: ERC20BridgeSource.Smoothy,
@@ -546,7 +554,7 @@ export class SamplerOperations {
toTokenIdx,
},
contract: this._samplerContract,
function: this._samplerContract.sampleBuysFromSmoothy,
function: this._samplerContract.sampleBuysFromSmoothyGlobal,
params: [
{
poolAddress: pool.poolAddress,
@@ -555,7 +563,6 @@ export class SamplerOperations {
},
new BigNumber(fromTokenIdx),
new BigNumber(toTokenIdx),
makerFillAmounts,
],
});
}
@@ -564,15 +571,15 @@ export class SamplerOperations {
poolInfo: BalancerV2PoolInfo,
makerToken: string,
takerToken: string,
takerFillAmounts: BigNumber[],
_takerFillAmounts: BigNumber[],
source: ERC20BridgeSource,
): SourceQuoteOperation<BalancerV2FillData> {
return new SamplerContractOperation({
source,
fillData: poolInfo,
contract: this._samplerContract,
function: this._samplerContract.sampleSellsFromBalancerV2,
params: [poolInfo, takerToken, makerToken, takerFillAmounts],
function: this._samplerContract.sampleSellsFromBalancerV2Global,
params: [poolInfo, takerToken, makerToken],
});
}
@@ -580,15 +587,15 @@ export class SamplerOperations {
poolInfo: BalancerV2PoolInfo,
makerToken: string,
takerToken: string,
makerFillAmounts: BigNumber[],
_makerFillAmounts: BigNumber[],
source: ERC20BridgeSource,
): SourceQuoteOperation<BalancerV2FillData> {
return new SamplerContractOperation({
source,
fillData: poolInfo,
contract: this._samplerContract,
function: this._samplerContract.sampleBuysFromBalancerV2,
params: [poolInfo, takerToken, makerToken, makerFillAmounts],
function: this._samplerContract.sampleBuysFromBalancerV2Global,
params: [poolInfo, takerToken, makerToken],
});
}
@@ -596,15 +603,15 @@ export class SamplerOperations {
poolAddress: string,
makerToken: string,
takerToken: string,
takerFillAmounts: BigNumber[],
_takerFillAmounts: BigNumber[],
source: ERC20BridgeSource,
): SourceQuoteOperation<BalancerFillData> {
return new SamplerContractOperation({
source,
fillData: { poolAddress },
contract: this._samplerContract,
function: this._samplerContract.sampleSellsFromBalancer,
params: [poolAddress, takerToken, makerToken, takerFillAmounts],
function: this._samplerContract.sampleSellsFromBalancerGlobal,
params: [poolAddress, takerToken, makerToken],
});
}
@@ -612,15 +619,15 @@ export class SamplerOperations {
poolAddress: string,
makerToken: string,
takerToken: string,
makerFillAmounts: BigNumber[],
_makerFillAmounts: BigNumber[],
source: ERC20BridgeSource,
): SourceQuoteOperation<BalancerFillData> {
return new SamplerContractOperation({
source,
fillData: { poolAddress },
contract: this._samplerContract,
function: this._samplerContract.sampleBuysFromBalancer,
params: [poolAddress, takerToken, makerToken, makerFillAmounts],
function: this._samplerContract.sampleBuysFromBalancerGlobal,
params: [poolAddress, takerToken, makerToken],
});
}
@@ -628,14 +635,14 @@ export class SamplerOperations {
router: string,
makerToken: string,
takerToken: string,
takerFillAmounts: BigNumber[],
_takerFillAmounts: BigNumber[],
): SourceQuoteOperation<GenericRouterFillData> {
return new SamplerContractOperation({
source: ERC20BridgeSource.MStable,
fillData: { router },
contract: this._samplerContract,
function: this._samplerContract.sampleSellsFromMStable,
params: [router, takerToken, makerToken, takerFillAmounts],
function: this._samplerContract.sampleSellsFromMStableGlobal,
params: [router, takerToken, makerToken],
});
}
@@ -643,14 +650,14 @@ export class SamplerOperations {
router: string,
makerToken: string,
takerToken: string,
makerFillAmounts: BigNumber[],
_makerFillAmounts: BigNumber[],
): SourceQuoteOperation<GenericRouterFillData> {
return new SamplerContractOperation({
source: ERC20BridgeSource.MStable,
fillData: { router },
contract: this._samplerContract,
function: this._samplerContract.sampleBuysFromMStable,
params: [router, takerToken, makerToken, makerFillAmounts],
function: this._samplerContract.sampleBuysFromMStableGlobal,
params: [router, takerToken, makerToken],
});
}
@@ -658,18 +665,18 @@ export class SamplerOperations {
registry: string,
makerToken: string,
takerToken: string,
takerFillAmounts: BigNumber[],
_takerFillAmounts: BigNumber[],
): SourceQuoteOperation<BancorFillData> {
const paths = this._bancorService ? this._bancorService.getPaths(takerToken, makerToken) : [];
return new SamplerContractOperation({
source: ERC20BridgeSource.Bancor,
contract: this._samplerContract,
function: this._samplerContract.sampleSellsFromBancor,
params: [{ registry, paths }, takerToken, makerToken, takerFillAmounts],
function: this._samplerContract.sampleSellsFromBancorGlobal,
params: [{ registry, paths }, takerToken, makerToken],
callback: (callResults: string, fillData: BancorFillData): BigNumber[] => {
const [networkAddress, path, samples] = this._samplerContract.getABIDecodedReturnData<
[string, string[], BigNumber[]]
>('sampleSellsFromBancor', callResults);
>('sampleSellsFromBancorGlobal', callResults);
fillData.networkAddress = networkAddress;
fillData.path = path;
return samples;
@@ -682,17 +689,17 @@ export class SamplerOperations {
registry: string,
makerToken: string,
takerToken: string,
makerFillAmounts: BigNumber[],
_makerFillAmounts: BigNumber[],
): SourceQuoteOperation<BancorFillData> {
return new SamplerContractOperation({
source: ERC20BridgeSource.Bancor,
contract: this._samplerContract,
function: this._samplerContract.sampleBuysFromBancor,
params: [{ registry, paths: [] }, takerToken, makerToken, makerFillAmounts],
function: this._samplerContract.sampleBuysFromBancorGlobal,
params: [{ registry, paths: [] }, takerToken, makerToken],
callback: (callResults: string, fillData: BancorFillData): BigNumber[] => {
const [networkAddress, path, samples] = this._samplerContract.getABIDecodedReturnData<
[string, string[], BigNumber[]]
>('sampleBuysFromBancor', callResults);
>('sampleBuysFromBancorGlobal', callResults);
fillData.networkAddress = networkAddress;
fillData.path = path;
return samples;
@@ -704,7 +711,7 @@ export class SamplerOperations {
registry: string,
makerToken: string,
takerToken: string,
takerFillAmounts: BigNumber[],
_takerFillAmounts: BigNumber[],
): SourceQuoteOperation<MooniswapFillData> {
// Mooniswap uses ETH instead of WETH, represented by address(0)
const mooniswapTakerToken =
@@ -714,11 +721,11 @@ export class SamplerOperations {
return new SamplerContractOperation({
source: ERC20BridgeSource.Mooniswap,
contract: this._samplerContract,
function: this._samplerContract.sampleSellsFromMooniswap,
params: [registry, mooniswapTakerToken, mooniswapMakerToken, takerFillAmounts],
function: this._samplerContract.sampleSellsFromMooniswapGlobal,
params: [registry, mooniswapTakerToken, mooniswapMakerToken],
callback: (callResults: string, fillData: MooniswapFillData): BigNumber[] => {
const [poolAddress, samples] = this._samplerContract.getABIDecodedReturnData<[string, BigNumber[]]>(
'sampleSellsFromMooniswap',
'sampleSellsFromMooniswapGlobal',
callResults,
);
fillData.poolAddress = poolAddress;
@@ -731,7 +738,7 @@ export class SamplerOperations {
registry: string,
makerToken: string,
takerToken: string,
makerFillAmounts: BigNumber[],
_makerFillAmounts: BigNumber[],
): SourceQuoteOperation<MooniswapFillData> {
// Mooniswap uses ETH instead of WETH, represented by address(0)
const mooniswapTakerToken =
@@ -741,11 +748,11 @@ export class SamplerOperations {
return new SamplerContractOperation({
source: ERC20BridgeSource.Mooniswap,
contract: this._samplerContract,
function: this._samplerContract.sampleBuysFromMooniswap,
params: [registry, mooniswapTakerToken, mooniswapMakerToken, makerFillAmounts],
function: this._samplerContract.sampleBuysFromMooniswapGlobal,
params: [registry, mooniswapTakerToken, mooniswapMakerToken],
callback: (callResults: string, fillData: MooniswapFillData): BigNumber[] => {
const [poolAddress, samples] = this._samplerContract.getABIDecodedReturnData<[string, BigNumber[]]>(
'sampleBuysFromMooniswap',
'sampleBuysFromMooniswapGlobal',
callResults,
);
fillData.poolAddress = poolAddress;
@@ -764,11 +771,11 @@ export class SamplerOperations {
return new SamplerContractOperation({
source,
contract: this._samplerContract,
function: this._samplerContract.sampleSellsFromUniswapV3,
params: [quoter, tokenAddressPath, takerFillAmounts],
function: this._samplerContract.sampleSellsFromUniswapV3Global,
params: [quoter, tokenAddressPath],
callback: (callResults: string, fillData: UniswapV3FillData): BigNumber[] => {
const [paths, samples] = this._samplerContract.getABIDecodedReturnData<[string[], BigNumber[]]>(
'sampleSellsFromUniswapV3',
'sampleSellsFromUniswapV3Global',
callResults,
);
fillData.router = router;
@@ -792,11 +799,11 @@ export class SamplerOperations {
return new SamplerContractOperation({
source,
contract: this._samplerContract,
function: this._samplerContract.sampleBuysFromUniswapV3,
params: [quoter, tokenAddressPath, makerFillAmounts],
function: this._samplerContract.sampleBuysFromUniswapV3Global,
params: [quoter, tokenAddressPath],
callback: (callResults: string, fillData: UniswapV3FillData): BigNumber[] => {
const [paths, samples] = this._samplerContract.getABIDecodedReturnData<[string[], BigNumber[]]>(
'sampleBuysFromUniswapV3',
'sampleBuysFromUniswapV3Global',
callResults,
);
fillData.router = router;
@@ -927,15 +934,15 @@ export class SamplerOperations {
poolAddress: string,
makerToken: string,
takerToken: string,
takerFillAmounts: BigNumber[],
_takerFillAmounts: BigNumber[],
source: ERC20BridgeSource = ERC20BridgeSource.Shell,
): SourceQuoteOperation<ShellFillData> {
return new SamplerContractOperation({
source,
fillData: { poolAddress },
contract: this._samplerContract,
function: this._samplerContract.sampleSellsFromShell,
params: [poolAddress, takerToken, makerToken, takerFillAmounts],
function: this._samplerContract.sampleSellsFromShellGlobal,
params: [poolAddress, takerToken, makerToken],
});
}
@@ -943,15 +950,15 @@ export class SamplerOperations {
poolAddress: string,
makerToken: string,
takerToken: string,
makerFillAmounts: BigNumber[],
_makerFillAmounts: BigNumber[],
source: ERC20BridgeSource = ERC20BridgeSource.Shell,
): SourceQuoteOperation {
return new SamplerContractOperation({
source,
fillData: { poolAddress },
contract: this._samplerContract,
function: this._samplerContract.sampleBuysFromShell,
params: [poolAddress, takerToken, makerToken, makerFillAmounts],
function: this._samplerContract.sampleBuysFromShellGlobal,
params: [poolAddress, takerToken, makerToken],
});
}
@@ -959,17 +966,17 @@ export class SamplerOperations {
opts: { registry: string; helper: string },
makerToken: string,
takerToken: string,
takerFillAmounts: BigNumber[],
_takerFillAmounts: BigNumber[],
): SourceQuoteOperation<DODOFillData> {
return new SamplerContractOperation({
source: ERC20BridgeSource.Dodo,
contract: this._samplerContract,
function: this._samplerContract.sampleSellsFromDODO,
params: [opts, takerToken, makerToken, takerFillAmounts],
function: this._samplerContract.sampleSellsFromDODOGlobal,
params: [opts, takerToken, makerToken],
callback: (callResults: string, fillData: DODOFillData): BigNumber[] => {
const [isSellBase, pool, samples] = this._samplerContract.getABIDecodedReturnData<
[boolean, string, BigNumber[]]
>('sampleSellsFromDODO', callResults);
>('sampleSellsFromDODOGlobal', callResults);
fillData.isSellBase = isSellBase;
fillData.poolAddress = pool;
fillData.helperAddress = opts.helper;
@@ -982,17 +989,17 @@ export class SamplerOperations {
opts: { registry: string; helper: string },
makerToken: string,
takerToken: string,
makerFillAmounts: BigNumber[],
_makerFillAmounts: BigNumber[],
): SourceQuoteOperation<DODOFillData> {
return new SamplerContractOperation({
source: ERC20BridgeSource.Dodo,
contract: this._samplerContract,
function: this._samplerContract.sampleBuysFromDODO,
params: [opts, takerToken, makerToken, makerFillAmounts],
function: this._samplerContract.sampleBuysFromDODOGlobal,
params: [opts, takerToken, makerToken],
callback: (callResults: string, fillData: DODOFillData): BigNumber[] => {
const [isSellBase, pool, samples] = this._samplerContract.getABIDecodedReturnData<
[boolean, string, BigNumber[]]
>('sampleBuysFromDODO', callResults);
>('sampleBuysFromDODOGlobal', callResults);
fillData.isSellBase = isSellBase;
fillData.poolAddress = pool;
fillData.helperAddress = opts.helper;
@@ -1006,17 +1013,17 @@ export class SamplerOperations {
offset: BigNumber,
makerToken: string,
takerToken: string,
takerFillAmounts: BigNumber[],
_takerFillAmounts: BigNumber[],
): SourceQuoteOperation<DODOFillData> {
return new SamplerContractOperation({
source: ERC20BridgeSource.DodoV2,
contract: this._samplerContract,
function: this._samplerContract.sampleSellsFromDODOV2,
params: [registry, offset, takerToken, makerToken, takerFillAmounts],
function: this._samplerContract.sampleSellsFromDODOV2Global,
params: [registry, offset, takerToken, makerToken],
callback: (callResults: string, fillData: DODOFillData): BigNumber[] => {
const [isSellBase, pool, samples] = this._samplerContract.getABIDecodedReturnData<
[boolean, string, BigNumber[]]
>('sampleSellsFromDODOV2', callResults);
>('sampleSellsFromDODOV2Global', callResults);
fillData.isSellBase = isSellBase;
fillData.poolAddress = pool;
return samples;
@@ -1029,17 +1036,17 @@ export class SamplerOperations {
offset: BigNumber,
makerToken: string,
takerToken: string,
makerFillAmounts: BigNumber[],
_makerFillAmounts: BigNumber[],
): SourceQuoteOperation<DODOFillData> {
return new SamplerContractOperation({
source: ERC20BridgeSource.DodoV2,
contract: this._samplerContract,
function: this._samplerContract.sampleBuysFromDODOV2,
params: [registry, offset, takerToken, makerToken, makerFillAmounts],
function: this._samplerContract.sampleBuysFromDODOV2Global,
params: [registry, offset, takerToken, makerToken],
callback: (callResults: string, fillData: DODOFillData): BigNumber[] => {
const [isSellBase, pool, samples] = this._samplerContract.getABIDecodedReturnData<
[boolean, string, BigNumber[]]
>('sampleSellsFromDODOV2', callResults);
>('sampleSellsFromDODOV2Global', callResults);
fillData.isSellBase = isSellBase;
fillData.poolAddress = pool;
return samples;
@@ -1051,7 +1058,7 @@ export class SamplerOperations {
psmInfo: PsmInfo,
makerToken: string,
takerToken: string,
takerFillAmounts: BigNumber[],
_takerFillAmounts: BigNumber[],
): SourceQuoteOperation<MakerPsmFillData> {
return new SamplerContractOperation({
source: ERC20BridgeSource.MakerPsm,
@@ -1062,8 +1069,8 @@ export class SamplerOperations {
...psmInfo,
},
contract: this._samplerContract,
function: this._samplerContract.sampleSellsFromMakerPsm,
params: [psmInfo, takerToken, makerToken, takerFillAmounts],
function: this._samplerContract.sampleSellsFromMakerPsmGlobal,
params: [psmInfo, takerToken, makerToken],
});
}
@@ -1071,7 +1078,7 @@ export class SamplerOperations {
psmInfo: PsmInfo,
makerToken: string,
takerToken: string,
makerFillAmounts: BigNumber[],
_makerFillAmounts: BigNumber[],
): SourceQuoteOperation<MakerPsmFillData> {
return new SamplerContractOperation({
source: ERC20BridgeSource.MakerPsm,
@@ -1082,8 +1089,8 @@ export class SamplerOperations {
...psmInfo,
},
contract: this._samplerContract,
function: this._samplerContract.sampleBuysFromMakerPsm,
params: [psmInfo, takerToken, makerToken, makerFillAmounts],
function: this._samplerContract.sampleBuysFromMakerPsmGlobal,
params: [psmInfo, takerToken, makerToken],
});
}
@@ -1091,7 +1098,7 @@ export class SamplerOperations {
lidoInfo: LidoInfo,
makerToken: string,
takerToken: string,
takerFillAmounts: BigNumber[],
_takerFillAmounts: BigNumber[],
): SourceQuoteOperation<LidoFillData> {
return new SamplerContractOperation({
source: ERC20BridgeSource.Lido,
@@ -1100,8 +1107,8 @@ export class SamplerOperations {
stEthTokenAddress: lidoInfo.stEthToken,
},
contract: this._samplerContract,
function: this._samplerContract.sampleSellsFromLido,
params: [lidoInfo, takerToken, makerToken, takerFillAmounts],
function: this._samplerContract.sampleSellsFromLidoGlobal,
params: [lidoInfo, takerToken, makerToken],
});
}
@@ -1109,7 +1116,7 @@ export class SamplerOperations {
lidoInfo: LidoInfo,
makerToken: string,
takerToken: string,
makerFillAmounts: BigNumber[],
_makerFillAmounts: BigNumber[],
): SourceQuoteOperation<LidoFillData> {
return new SamplerContractOperation({
source: ERC20BridgeSource.Lido,
@@ -1118,8 +1125,8 @@ export class SamplerOperations {
stEthTokenAddress: lidoInfo.stEthToken,
},
contract: this._samplerContract,
function: this._samplerContract.sampleBuysFromLido,
params: [lidoInfo, takerToken, makerToken, makerFillAmounts],
function: this._samplerContract.sampleBuysFromLidoGlobal,
params: [lidoInfo, takerToken, makerToken],
});
}
@@ -1155,14 +1162,14 @@ export class SamplerOperations {
cToken: string,
makerToken: string,
takerToken: string,
takerFillAmounts: BigNumber[],
_takerFillAmounts: BigNumber[],
): SourceQuoteOperation<CompoundFillData> {
return new SamplerContractOperation({
source: ERC20BridgeSource.Compound,
fillData: { cToken, takerToken, makerToken },
contract: this._samplerContract,
function: this._samplerContract.sampleSellsFromCompound,
params: [cToken, takerToken, makerToken, takerFillAmounts],
function: this._samplerContract.sampleSellsFromCompoundGlobal,
params: [cToken, takerToken, makerToken],
});
}
@@ -1170,14 +1177,14 @@ export class SamplerOperations {
cToken: string,
makerToken: string,
takerToken: string,
makerFillAmounts: BigNumber[],
_makerFillAmounts: BigNumber[],
): SourceQuoteOperation<CompoundFillData> {
return new SamplerContractOperation({
source: ERC20BridgeSource.Compound,
fillData: { cToken, takerToken, makerToken },
contract: this._samplerContract,
function: this._samplerContract.sampleBuysFromCompound,
params: [cToken, takerToken, makerToken, makerFillAmounts],
function: this._samplerContract.sampleBuysFromCompoundGlobal,
params: [cToken, takerToken, makerToken],
});
}

View File

@@ -12,15 +12,19 @@ import * as BalancerV2Sampler from '../test/generated-artifacts/BalancerV2Sample
import * as BancorSampler from '../test/generated-artifacts/BancorSampler.json';
import * as CompoundSampler from '../test/generated-artifacts/CompoundSampler.json';
import * as CurveSampler from '../test/generated-artifacts/CurveSampler.json';
import * as CurveSamplerTest from '../test/generated-artifacts/CurveSamplerTest.json';
import * as DODOSampler from '../test/generated-artifacts/DODOSampler.json';
import * as DODOV2Sampler from '../test/generated-artifacts/DODOV2Sampler.json';
import * as DSTest from '../test/generated-artifacts/DSTest.json';
import * as DummyLiquidityProvider from '../test/generated-artifacts/DummyLiquidityProvider.json';
import * as ERC20BridgeSampler from '../test/generated-artifacts/ERC20BridgeSampler.json';
import * as FakeTaker from '../test/generated-artifacts/FakeTaker.json';
import * as IBalancer from '../test/generated-artifacts/IBalancer.json';
import * as IBancor from '../test/generated-artifacts/IBancor.json';
import * as ICurve from '../test/generated-artifacts/ICurve.json';
import * as IERC20TokenV06 from '../test/generated-artifacts/IERC20TokenV06.json';
import * as IKyberNetwork from '../test/generated-artifacts/IKyberNetwork.json';
import * as ILiquidityProvider from '../test/generated-artifacts/ILiquidityProvider.json';
import * as IMooniswap from '../test/generated-artifacts/IMooniswap.json';
import * as IMStable from '../test/generated-artifacts/IMStable.json';
import * as IMultiBridge from '../test/generated-artifacts/IMultiBridge.json';
@@ -30,6 +34,8 @@ import * as IUniswapExchangeQuotes from '../test/generated-artifacts/IUniswapExc
import * as IUniswapV2Router01 from '../test/generated-artifacts/IUniswapV2Router01.json';
import * as KyberDmmSampler from '../test/generated-artifacts/KyberDmmSampler.json';
import * as KyberSampler from '../test/generated-artifacts/KyberSampler.json';
import * as LibBytes from '../test/generated-artifacts/LibBytes.json';
import * as LibSafeMath from '../test/generated-artifacts/LibSafeMath.json';
import * as LidoSampler from '../test/generated-artifacts/LidoSampler.json';
import * as LiquidityProviderSampler from '../test/generated-artifacts/LiquidityProviderSampler.json';
import * as MakerPSMSampler from '../test/generated-artifacts/MakerPSMSampler.json';
@@ -37,14 +43,17 @@ import * as MooniswapSampler from '../test/generated-artifacts/MooniswapSampler.
import * as MStableSampler from '../test/generated-artifacts/MStableSampler.json';
import * as MultiBridgeSampler from '../test/generated-artifacts/MultiBridgeSampler.json';
import * as NativeOrderSampler from '../test/generated-artifacts/NativeOrderSampler.json';
import * as SamplerBase from '../test/generated-artifacts/SamplerBase.json';
import * as SamplerUtils from '../test/generated-artifacts/SamplerUtils.json';
import * as ShellSampler from '../test/generated-artifacts/ShellSampler.json';
import * as SmoothySampler from '../test/generated-artifacts/SmoothySampler.json';
import * as TestBase from '../test/generated-artifacts/TestBase.json';
import * as TestERC20BridgeSampler from '../test/generated-artifacts/TestERC20BridgeSampler.json';
import * as TestNativeOrderSampler from '../test/generated-artifacts/TestNativeOrderSampler.json';
import * as TwoHopSampler from '../test/generated-artifacts/TwoHopSampler.json';
import * as UniswapSampler from '../test/generated-artifacts/UniswapSampler.json';
import * as UniswapV2Sampler from '../test/generated-artifacts/UniswapV2Sampler.json';
import * as UniswapV2SamplerTest from '../test/generated-artifacts/UniswapV2SamplerTest.json';
import * as UniswapV3Sampler from '../test/generated-artifacts/UniswapV3Sampler.json';
import * as UtilitySampler from '../test/generated-artifacts/UtilitySampler.json';
export const artifacts = {
@@ -61,6 +70,8 @@ export const artifacts = {
FakeTaker: FakeTaker as ContractArtifact,
KyberDmmSampler: KyberDmmSampler as ContractArtifact,
KyberSampler: KyberSampler as ContractArtifact,
LibBytes: LibBytes as ContractArtifact,
LibSafeMath: LibSafeMath as ContractArtifact,
LidoSampler: LidoSampler as ContractArtifact,
LiquidityProviderSampler: LiquidityProviderSampler as ContractArtifact,
MStableSampler: MStableSampler as ContractArtifact,
@@ -68,6 +79,7 @@ export const artifacts = {
MooniswapSampler: MooniswapSampler as ContractArtifact,
MultiBridgeSampler: MultiBridgeSampler as ContractArtifact,
NativeOrderSampler: NativeOrderSampler as ContractArtifact,
SamplerBase: SamplerBase as ContractArtifact,
SamplerUtils: SamplerUtils as ContractArtifact,
ShellSampler: ShellSampler as ContractArtifact,
SmoothySampler: SmoothySampler as ContractArtifact,
@@ -79,7 +91,9 @@ export const artifacts = {
IBalancer: IBalancer as ContractArtifact,
IBancor: IBancor as ContractArtifact,
ICurve: ICurve as ContractArtifact,
IERC20TokenV06: IERC20TokenV06 as ContractArtifact,
IKyberNetwork: IKyberNetwork as ContractArtifact,
ILiquidityProvider: ILiquidityProvider as ContractArtifact,
IMStable: IMStable as ContractArtifact,
IMooniswap: IMooniswap as ContractArtifact,
IMultiBridge: IMultiBridge as ContractArtifact,
@@ -87,7 +101,11 @@ export const artifacts = {
ISmoothy: ISmoothy as ContractArtifact,
IUniswapExchangeQuotes: IUniswapExchangeQuotes as ContractArtifact,
IUniswapV2Router01: IUniswapV2Router01 as ContractArtifact,
CurveSamplerTest: CurveSamplerTest as ContractArtifact,
DSTest: DSTest as ContractArtifact,
DummyLiquidityProvider: DummyLiquidityProvider as ContractArtifact,
TestBase: TestBase as ContractArtifact,
TestERC20BridgeSampler: TestERC20BridgeSampler as ContractArtifact,
TestNativeOrderSampler: TestNativeOrderSampler as ContractArtifact,
UniswapV2SamplerTest: UniswapV2SamplerTest as ContractArtifact,
};

View File

@@ -61,8 +61,9 @@ blockchainTests.skip('Mainnet Sampler Tests', env => {
it('samples buys from Curve DAI->USDC', async () => {
// From DAI to USDC
// I want to buy 1 USDC
await testContract.setSampleValues([toBaseUnitAmount(1, 6)]).awaitTransactionSuccessAsync();
const samples = await testContract
.sampleBuysFromCurve(CURVE_INFO, DAI_TOKEN_INDEX, USDC_TOKEN_INDEX, [toBaseUnitAmount(1, 6)])
.sampleBuysFromCurveGlobal(CURVE_INFO, DAI_TOKEN_INDEX, USDC_TOKEN_INDEX)
.callAsync({ overrides });
expect(samples.length).to.be.bignumber.greaterThan(0);
expect(samples[0]).to.be.bignumber.greaterThan(0);
@@ -71,8 +72,9 @@ blockchainTests.skip('Mainnet Sampler Tests', env => {
it('samples buys from Curve USDC->DAI', async () => {
// From USDC to DAI
// I want to buy 1 DAI
await testContract.setSampleValues([toBaseUnitAmount(1)]).awaitTransactionSuccessAsync();
const samples = await testContract
.sampleBuysFromCurve(CURVE_INFO, USDC_TOKEN_INDEX, DAI_TOKEN_INDEX, [toBaseUnitAmount(1)])
.sampleBuysFromCurveGlobal(CURVE_INFO, USDC_TOKEN_INDEX, DAI_TOKEN_INDEX)
.callAsync({ overrides });
expect(samples.length).to.be.bignumber.greaterThan(0);
expect(samples[0]).to.be.bignumber.greaterThan(0);
@@ -117,8 +119,9 @@ blockchainTests.skip('Mainnet Sampler Tests', env => {
it('samples buys from Kyber WETH->DAI', async () => {
// From ETH to DAI
// I want to buy 1 DAI
await testContract.setSampleValues([toBaseUnitAmount(1)]).awaitTransactionSuccessAsync();
const [, samples] = await testContract
.sampleBuysFromKyberNetwork(KYBER_OPTS, WETH, DAI, [toBaseUnitAmount(1)])
.sampleBuysFromKyberNetworkGlobal(KYBER_OPTS, WETH, DAI)
.callAsync({ overrides });
expect(samples.length).to.be.bignumber.greaterThan(0);
expect(samples[0]).to.be.bignumber.greaterThan(0);
@@ -127,8 +130,9 @@ blockchainTests.skip('Mainnet Sampler Tests', env => {
it('samples buys from Kyber DAI->WETH', async () => {
// From USDC to DAI
// I want to buy 1 WETH
await testContract.setSampleValues([toBaseUnitAmount(1)]).awaitTransactionSuccessAsync();
const [, samples] = await testContract
.sampleBuysFromKyberNetwork(KYBER_OPTS, DAI, WETH, [toBaseUnitAmount(1)])
.sampleBuysFromKyberNetworkGlobal(KYBER_OPTS, DAI, WETH)
.callAsync({ overrides });
expect(samples.length).to.be.bignumber.greaterThan(0);
expect(samples[0]).to.be.bignumber.greaterThan(0);

View File

@@ -426,13 +426,13 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
});
it('throws if tokens are the same', async () => {
const tx = testContract.sampleBuysFromKyberNetwork(kyberOpts, MAKER_TOKEN, MAKER_TOKEN, []).callAsync();
const tx = testContract.sampleBuysFromKyberNetworkGlobal(kyberOpts, MAKER_TOKEN, MAKER_TOKEN).callAsync();
return expect(tx).to.revertWith(INVALID_TOKEN_PAIR_ERROR);
});
it('can return no quotes', async () => {
const [, , quotes] = await testContract
.sampleBuysFromKyberNetwork(kyberOpts, TAKER_TOKEN, MAKER_TOKEN, [])
.sampleBuysFromKyberNetworkGlobal(kyberOpts, TAKER_TOKEN, MAKER_TOKEN)
.callAsync();
expect(quotes).to.deep.eq([]);
});
@@ -440,8 +440,9 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
it('can quote token -> token', async () => {
const sampleAmounts = getSampleAmounts(TAKER_TOKEN);
const [expectedQuotes] = getDeterministicBuyQuotes(TAKER_TOKEN, MAKER_TOKEN, ['Kyber'], sampleAmounts);
await testContract.setSampleValues(sampleAmounts).awaitTransactionSuccessAsync();
const [, , quotes] = await testContract
.sampleBuysFromKyberNetwork(kyberOpts, TAKER_TOKEN, MAKER_TOKEN, sampleAmounts)
.sampleBuysFromKyberNetworkGlobal(kyberOpts, TAKER_TOKEN, MAKER_TOKEN)
.callAsync();
expectQuotesWithinRange(quotes, expectedQuotes, ACCEPTABLE_SLIPPAGE);
});
@@ -450,8 +451,9 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
const sampleAmounts = getSampleAmounts(TAKER_TOKEN);
const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT);
await enableFailTriggerAsync();
await testContract.setSampleValues(sampleAmounts).awaitTransactionSuccessAsync();
const [, , quotes] = await testContract
.sampleBuysFromKyberNetwork(kyberOpts, TAKER_TOKEN, MAKER_TOKEN, sampleAmounts)
.sampleBuysFromKyberNetworkGlobal(kyberOpts, TAKER_TOKEN, MAKER_TOKEN)
.callAsync();
expect(quotes).to.deep.eq(expectedQuotes);
});
@@ -459,8 +461,9 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
it('can quote token -> ETH', async () => {
const sampleAmounts = getSampleAmounts(TAKER_TOKEN);
const [expectedQuotes] = getDeterministicBuyQuotes(TAKER_TOKEN, WETH_ADDRESS, ['Kyber'], sampleAmounts);
await testContract.setSampleValues(sampleAmounts).awaitTransactionSuccessAsync();
const [, , quotes] = await testContract
.sampleBuysFromKyberNetwork(kyberOpts, TAKER_TOKEN, WETH_ADDRESS, sampleAmounts)
.sampleBuysFromKyberNetworkGlobal(kyberOpts, TAKER_TOKEN, WETH_ADDRESS)
.callAsync();
expectQuotesWithinRange(quotes, expectedQuotes, ACCEPTABLE_SLIPPAGE);
});
@@ -469,8 +472,9 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
const sampleAmounts = getSampleAmounts(TAKER_TOKEN);
const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT);
await enableFailTriggerAsync();
await testContract.setSampleValues(sampleAmounts).awaitTransactionSuccessAsync();
const [, , quotes] = await testContract
.sampleBuysFromKyberNetwork(kyberOpts, TAKER_TOKEN, WETH_ADDRESS, sampleAmounts)
.sampleBuysFromKyberNetworkGlobal(kyberOpts, TAKER_TOKEN, WETH_ADDRESS)
.callAsync();
expect(quotes).to.deep.eq(expectedQuotes);
});
@@ -478,8 +482,9 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
it('can quote ETH -> token', async () => {
const sampleAmounts = getSampleAmounts(TAKER_TOKEN);
const [expectedQuotes] = getDeterministicBuyQuotes(WETH_ADDRESS, TAKER_TOKEN, ['Kyber'], sampleAmounts);
await testContract.setSampleValues(sampleAmounts).awaitTransactionSuccessAsync();
const [, , quotes] = await testContract
.sampleBuysFromKyberNetwork(kyberOpts, WETH_ADDRESS, TAKER_TOKEN, sampleAmounts)
.sampleBuysFromKyberNetworkGlobal(kyberOpts, WETH_ADDRESS, TAKER_TOKEN)
.callAsync();
expectQuotesWithinRange(quotes, expectedQuotes, ACCEPTABLE_SLIPPAGE);
});
@@ -488,8 +493,9 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
const sampleAmounts = getSampleAmounts(TAKER_TOKEN);
const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT);
await enableFailTriggerAsync();
await testContract.setSampleValues(sampleAmounts).awaitTransactionSuccessAsync();
const [, , quotes] = await testContract
.sampleBuysFromKyberNetwork(kyberOpts, WETH_ADDRESS, TAKER_TOKEN, sampleAmounts)
.sampleBuysFromKyberNetworkGlobal(kyberOpts, WETH_ADDRESS, TAKER_TOKEN)
.callAsync();
expect(quotes).to.deep.eq(expectedQuotes);
});
@@ -502,13 +508,13 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
});
it('throws if tokens are the same', async () => {
const tx = testContract.sampleSellsFromUniswap(UNISWAP_ADDRESS, MAKER_TOKEN, MAKER_TOKEN, []).callAsync();
const tx = testContract.sampleSellsFromUniswapGlobal(UNISWAP_ADDRESS, MAKER_TOKEN, MAKER_TOKEN).callAsync();
return expect(tx).to.revertWith(INVALID_TOKEN_PAIR_ERROR);
});
it('can return no quotes', async () => {
const quotes = await testContract
.sampleSellsFromUniswap(UNISWAP_ADDRESS, TAKER_TOKEN, MAKER_TOKEN, [])
.sampleSellsFromUniswapGlobal(UNISWAP_ADDRESS, TAKER_TOKEN, MAKER_TOKEN)
.callAsync();
expect(quotes).to.deep.eq([]);
});
@@ -516,8 +522,9 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
it('can quote token -> token', async () => {
const sampleAmounts = getSampleAmounts(TAKER_TOKEN);
const [expectedQuotes] = getDeterministicSellQuotes(TAKER_TOKEN, MAKER_TOKEN, ['Uniswap'], sampleAmounts);
await testContract.setSampleValues(sampleAmounts).awaitTransactionSuccessAsync();
const quotes = await testContract
.sampleSellsFromUniswap(UNISWAP_ADDRESS, TAKER_TOKEN, MAKER_TOKEN, sampleAmounts)
.sampleSellsFromUniswapGlobal(UNISWAP_ADDRESS, TAKER_TOKEN, MAKER_TOKEN)
.callAsync();
expect(quotes).to.deep.eq(expectedQuotes);
});
@@ -526,8 +533,9 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
const sampleAmounts = getSampleAmounts(TAKER_TOKEN);
const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT);
await enableFailTriggerAsync();
await testContract.setSampleValues(sampleAmounts).awaitTransactionSuccessAsync();
const quotes = await testContract
.sampleSellsFromUniswap(UNISWAP_ADDRESS, TAKER_TOKEN, MAKER_TOKEN, sampleAmounts)
.sampleSellsFromUniswapGlobal(UNISWAP_ADDRESS, TAKER_TOKEN, MAKER_TOKEN)
.callAsync();
expect(quotes).to.deep.eq(expectedQuotes);
});
@@ -535,8 +543,9 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
it('can quote token -> ETH', async () => {
const sampleAmounts = getSampleAmounts(TAKER_TOKEN);
const [expectedQuotes] = getDeterministicSellQuotes(TAKER_TOKEN, WETH_ADDRESS, ['Uniswap'], sampleAmounts);
await testContract.setSampleValues(sampleAmounts).awaitTransactionSuccessAsync();
const quotes = await testContract
.sampleSellsFromUniswap(UNISWAP_ADDRESS, TAKER_TOKEN, UNISWAP_ETH_ADDRESS, sampleAmounts)
.sampleSellsFromUniswapGlobal(UNISWAP_ADDRESS, TAKER_TOKEN, UNISWAP_ETH_ADDRESS)
.callAsync();
expect(quotes).to.deep.eq(expectedQuotes);
});
@@ -545,8 +554,9 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
const sampleAmounts = getSampleAmounts(TAKER_TOKEN);
const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT);
await enableFailTriggerAsync();
await testContract.setSampleValues(sampleAmounts).awaitTransactionSuccessAsync();
const quotes = await testContract
.sampleSellsFromUniswap(UNISWAP_ADDRESS, TAKER_TOKEN, UNISWAP_ETH_ADDRESS, sampleAmounts)
.sampleSellsFromUniswapGlobal(UNISWAP_ADDRESS, TAKER_TOKEN, UNISWAP_ETH_ADDRESS)
.callAsync();
expect(quotes).to.deep.eq(expectedQuotes);
});
@@ -554,8 +564,9 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
it('can quote ETH -> token', async () => {
const sampleAmounts = getSampleAmounts(TAKER_TOKEN);
const [expectedQuotes] = getDeterministicSellQuotes(WETH_ADDRESS, TAKER_TOKEN, ['Uniswap'], sampleAmounts);
await testContract.setSampleValues(sampleAmounts).awaitTransactionSuccessAsync();
const quotes = await testContract
.sampleSellsFromUniswap(UNISWAP_ADDRESS, UNISWAP_ETH_ADDRESS, TAKER_TOKEN, sampleAmounts)
.sampleSellsFromUniswapGlobal(UNISWAP_ADDRESS, UNISWAP_ETH_ADDRESS, TAKER_TOKEN)
.callAsync();
expect(quotes).to.deep.eq(expectedQuotes);
});
@@ -564,8 +575,9 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
const sampleAmounts = getSampleAmounts(TAKER_TOKEN);
const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT);
await enableFailTriggerAsync();
await testContract.setSampleValues(sampleAmounts).awaitTransactionSuccessAsync();
const quotes = await testContract
.sampleSellsFromUniswap(UNISWAP_ADDRESS, UNISWAP_ETH_ADDRESS, TAKER_TOKEN, sampleAmounts)
.sampleSellsFromUniswapGlobal(UNISWAP_ADDRESS, UNISWAP_ETH_ADDRESS, TAKER_TOKEN)
.callAsync();
expect(quotes).to.deep.eq(expectedQuotes);
});
@@ -574,8 +586,9 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
const nonExistantToken = randomAddress();
const sampleAmounts = getSampleAmounts(TAKER_TOKEN);
const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT);
await testContract.setSampleValues(sampleAmounts).awaitTransactionSuccessAsync();
const quotes = await testContract
.sampleSellsFromUniswap(UNISWAP_ADDRESS, TAKER_TOKEN, nonExistantToken, sampleAmounts)
.sampleSellsFromUniswapGlobal(UNISWAP_ADDRESS, TAKER_TOKEN, nonExistantToken)
.callAsync();
expect(quotes).to.deep.eq(expectedQuotes);
});
@@ -584,8 +597,9 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
const nonExistantToken = randomAddress();
const sampleAmounts = getSampleAmounts(nonExistantToken);
const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT);
await testContract.setSampleValues(sampleAmounts).awaitTransactionSuccessAsync();
const quotes = await testContract
.sampleSellsFromUniswap(UNISWAP_ADDRESS, nonExistantToken, MAKER_TOKEN, sampleAmounts)
.sampleSellsFromUniswapGlobal(UNISWAP_ADDRESS, nonExistantToken, MAKER_TOKEN)
.callAsync();
expect(quotes).to.deep.eq(expectedQuotes);
});
@@ -598,13 +612,13 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
});
it('throws if tokens are the same', async () => {
const tx = testContract.sampleBuysFromUniswap(UNISWAP_ADDRESS, MAKER_TOKEN, MAKER_TOKEN, []).callAsync();
const tx = testContract.sampleBuysFromUniswapGlobal(UNISWAP_ADDRESS, MAKER_TOKEN, MAKER_TOKEN).callAsync();
return expect(tx).to.revertWith(INVALID_TOKEN_PAIR_ERROR);
});
it('can return no quotes', async () => {
const quotes = await testContract
.sampleBuysFromUniswap(UNISWAP_ADDRESS, TAKER_TOKEN, MAKER_TOKEN, [])
.sampleBuysFromUniswapGlobal(UNISWAP_ADDRESS, TAKER_TOKEN, MAKER_TOKEN)
.callAsync();
expect(quotes).to.deep.eq([]);
});
@@ -612,8 +626,9 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
it('can quote token -> token', async () => {
const sampleAmounts = getSampleAmounts(MAKER_TOKEN);
const [expectedQuotes] = getDeterministicBuyQuotes(TAKER_TOKEN, MAKER_TOKEN, ['Uniswap'], sampleAmounts);
await testContract.setSampleValues(sampleAmounts).awaitTransactionSuccessAsync();
const quotes = await testContract
.sampleBuysFromUniswap(UNISWAP_ADDRESS, TAKER_TOKEN, MAKER_TOKEN, sampleAmounts)
.sampleBuysFromUniswapGlobal(UNISWAP_ADDRESS, TAKER_TOKEN, MAKER_TOKEN)
.callAsync();
expect(quotes).to.deep.eq(expectedQuotes);
});
@@ -622,8 +637,9 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
const sampleAmounts = getSampleAmounts(MAKER_TOKEN);
const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT);
await enableFailTriggerAsync();
await testContract.setSampleValues(sampleAmounts).awaitTransactionSuccessAsync();
const quotes = await testContract
.sampleBuysFromUniswap(UNISWAP_ADDRESS, TAKER_TOKEN, MAKER_TOKEN, sampleAmounts)
.sampleBuysFromUniswapGlobal(UNISWAP_ADDRESS, TAKER_TOKEN, MAKER_TOKEN)
.callAsync();
expect(quotes).to.deep.eq(expectedQuotes);
});
@@ -632,7 +648,7 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
const sampleAmounts = getSampleAmounts(MAKER_TOKEN);
const [expectedQuotes] = getDeterministicBuyQuotes(TAKER_TOKEN, WETH_ADDRESS, ['Uniswap'], sampleAmounts);
const quotes = await testContract
.sampleBuysFromUniswap(UNISWAP_ADDRESS, TAKER_TOKEN, UNISWAP_ETH_ADDRESS, sampleAmounts)
.sampleBuysFromUniswapGlobal(UNISWAP_ADDRESS, TAKER_TOKEN, UNISWAP_ETH_ADDRESS)
.callAsync();
expect(quotes).to.deep.eq(expectedQuotes);
});
@@ -641,8 +657,9 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
const sampleAmounts = getSampleAmounts(MAKER_TOKEN);
const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT);
await enableFailTriggerAsync();
await testContract.setSampleValues(sampleAmounts).awaitTransactionSuccessAsync();
const quotes = await testContract
.sampleBuysFromUniswap(UNISWAP_ADDRESS, TAKER_TOKEN, UNISWAP_ETH_ADDRESS, sampleAmounts)
.sampleBuysFromUniswapGlobal(UNISWAP_ADDRESS, TAKER_TOKEN, UNISWAP_ETH_ADDRESS)
.callAsync();
expect(quotes).to.deep.eq(expectedQuotes);
});
@@ -650,8 +667,9 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
it('can quote ETH -> token', async () => {
const sampleAmounts = getSampleAmounts(MAKER_TOKEN);
const [expectedQuotes] = getDeterministicBuyQuotes(WETH_ADDRESS, TAKER_TOKEN, ['Uniswap'], sampleAmounts);
await testContract.setSampleValues(sampleAmounts).awaitTransactionSuccessAsync();
const quotes = await testContract
.sampleBuysFromUniswap(UNISWAP_ADDRESS, UNISWAP_ETH_ADDRESS, TAKER_TOKEN, sampleAmounts)
.sampleBuysFromUniswapGlobal(UNISWAP_ADDRESS, UNISWAP_ETH_ADDRESS, TAKER_TOKEN)
.callAsync();
expect(quotes).to.deep.eq(expectedQuotes);
});
@@ -660,8 +678,9 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
const sampleAmounts = getSampleAmounts(MAKER_TOKEN);
const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT);
await enableFailTriggerAsync();
await testContract.setSampleValues(sampleAmounts).awaitTransactionSuccessAsync();
const quotes = await testContract
.sampleBuysFromUniswap(UNISWAP_ADDRESS, UNISWAP_ETH_ADDRESS, TAKER_TOKEN, sampleAmounts)
.sampleBuysFromUniswapGlobal(UNISWAP_ADDRESS, UNISWAP_ETH_ADDRESS, TAKER_TOKEN)
.callAsync();
expect(quotes).to.deep.eq(expectedQuotes);
});
@@ -670,8 +689,9 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
const nonExistantToken = randomAddress();
const sampleAmounts = getSampleAmounts(nonExistantToken);
const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT);
await testContract.setSampleValues(sampleAmounts).awaitTransactionSuccessAsync();
const quotes = await testContract
.sampleBuysFromUniswap(UNISWAP_ADDRESS, TAKER_TOKEN, nonExistantToken, sampleAmounts)
.sampleBuysFromUniswapGlobal(UNISWAP_ADDRESS, TAKER_TOKEN, nonExistantToken)
.callAsync();
expect(quotes).to.deep.eq(expectedQuotes);
});
@@ -680,8 +700,9 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
const nonExistantToken = randomAddress();
const sampleAmounts = getSampleAmounts(MAKER_TOKEN);
const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT);
await testContract.setSampleValues(sampleAmounts).awaitTransactionSuccessAsync();
const quotes = await testContract
.sampleBuysFromUniswap(UNISWAP_ADDRESS, nonExistantToken, MAKER_TOKEN, sampleAmounts)
.sampleBuysFromUniswapGlobal(UNISWAP_ADDRESS, nonExistantToken, MAKER_TOKEN)
.callAsync();
expect(quotes).to.deep.eq(expectedQuotes);
});
@@ -700,11 +721,12 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
env.txDefaults,
{},
);
await testContract.setSampleValues(sampleAmounts).awaitTransactionSuccessAsync();
});
it('should be able to query sells from the liquidity provider', async () => {
const quotes = await testContract
.sampleSellsFromLiquidityProvider(liquidityProvider.address, yAsset, xAsset, sampleAmounts)
.sampleSellsFromLiquidityProviderGlobal(liquidityProvider.address, yAsset, xAsset)
.callAsync();
quotes.forEach((value, idx) => {
expect(value).is.bignumber.eql(sampleAmounts[idx].minus(1));
@@ -713,7 +735,7 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
it('should be able to query buys from the liquidity provider', async () => {
const quotes = await testContract
.sampleBuysFromLiquidityProvider(liquidityProvider.address, yAsset, xAsset, sampleAmounts)
.sampleBuysFromLiquidityProviderGlobal(liquidityProvider.address, yAsset, xAsset)
.callAsync();
quotes.forEach((value, idx) => {
expect(value).is.bignumber.eql(sampleAmounts[idx].plus(1));
@@ -722,7 +744,7 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
it('should just return zeros if the liquidity provider does not exist', async () => {
const quotes = await testContract
.sampleBuysFromLiquidityProvider(randomAddress(), yAsset, xAsset, sampleAmounts)
.sampleBuysFromLiquidityProviderGlobal(randomAddress(), yAsset, xAsset)
.callAsync();
quotes.forEach(value => {
expect(value).is.bignumber.eql(constants.ZERO_AMOUNT);
@@ -737,7 +759,7 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
it('can return no quotes', async () => {
const quotes = await testContract
.sampleSellsFromUniswapV2(UNISWAP_V2_ROUTER, [TAKER_TOKEN, MAKER_TOKEN], [])
.sampleSellsFromUniswapV2Global(UNISWAP_V2_ROUTER, [TAKER_TOKEN, MAKER_TOKEN])
.callAsync();
expect(quotes).to.deep.eq([]);
});
@@ -745,8 +767,9 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
it('can quote token -> token', async () => {
const sampleAmounts = getSampleAmounts(TAKER_TOKEN);
const expectedQuotes = predictSellQuotes([TAKER_TOKEN, MAKER_TOKEN], sampleAmounts);
await testContract.setSampleValues(sampleAmounts).awaitTransactionSuccessAsync();
const quotes = await testContract
.sampleSellsFromUniswapV2(UNISWAP_V2_ROUTER, [TAKER_TOKEN, MAKER_TOKEN], sampleAmounts)
.sampleSellsFromUniswapV2Global(UNISWAP_V2_ROUTER, [TAKER_TOKEN, MAKER_TOKEN])
.callAsync();
expect(quotes).to.deep.eq(expectedQuotes);
});
@@ -755,8 +778,9 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
const sampleAmounts = getSampleAmounts(TAKER_TOKEN);
const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT);
await enableFailTriggerAsync();
await testContract.setSampleValues(sampleAmounts).awaitTransactionSuccessAsync();
const quotes = await testContract
.sampleSellsFromUniswapV2(UNISWAP_V2_ROUTER, [TAKER_TOKEN, MAKER_TOKEN], sampleAmounts)
.sampleSellsFromUniswapV2Global(UNISWAP_V2_ROUTER, [TAKER_TOKEN, MAKER_TOKEN])
.callAsync();
expect(quotes).to.deep.eq(expectedQuotes);
});
@@ -765,12 +789,9 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
const intermediateToken = randomAddress();
const sampleAmounts = getSampleAmounts(TAKER_TOKEN);
const expectedQuotes = predictSellQuotes([TAKER_TOKEN, intermediateToken, MAKER_TOKEN], sampleAmounts);
await testContract.setSampleValues(sampleAmounts).awaitTransactionSuccessAsync();
const quotes = await testContract
.sampleSellsFromUniswapV2(
UNISWAP_V2_ROUTER,
[TAKER_TOKEN, intermediateToken, MAKER_TOKEN],
sampleAmounts,
)
.sampleSellsFromUniswapV2Global(UNISWAP_V2_ROUTER, [TAKER_TOKEN, intermediateToken, MAKER_TOKEN])
.callAsync();
expect(quotes).to.deep.eq(expectedQuotes);
});
@@ -783,7 +804,7 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
it('can return no quotes', async () => {
const quotes = await testContract
.sampleBuysFromUniswapV2(UNISWAP_V2_ROUTER, [TAKER_TOKEN, MAKER_TOKEN], [])
.sampleBuysFromUniswapV2Global(UNISWAP_V2_ROUTER, [TAKER_TOKEN, MAKER_TOKEN])
.callAsync();
expect(quotes).to.deep.eq([]);
});
@@ -791,8 +812,9 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
it('can quote token -> token', async () => {
const sampleAmounts = getSampleAmounts(MAKER_TOKEN);
const expectedQuotes = predictBuyQuotes([TAKER_TOKEN, MAKER_TOKEN], sampleAmounts);
await testContract.setSampleValues(sampleAmounts).awaitTransactionSuccessAsync();
const quotes = await testContract
.sampleBuysFromUniswapV2(UNISWAP_V2_ROUTER, [TAKER_TOKEN, MAKER_TOKEN], sampleAmounts)
.sampleBuysFromUniswapV2Global(UNISWAP_V2_ROUTER, [TAKER_TOKEN, MAKER_TOKEN])
.callAsync();
expect(quotes).to.deep.eq(expectedQuotes);
});
@@ -801,8 +823,9 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
const sampleAmounts = getSampleAmounts(MAKER_TOKEN);
const expectedQuotes = _.times(sampleAmounts.length, () => constants.ZERO_AMOUNT);
await enableFailTriggerAsync();
await testContract.setSampleValues(sampleAmounts).awaitTransactionSuccessAsync();
const quotes = await testContract
.sampleBuysFromUniswapV2(UNISWAP_V2_ROUTER, [TAKER_TOKEN, MAKER_TOKEN], sampleAmounts)
.sampleBuysFromUniswapV2Global(UNISWAP_V2_ROUTER, [TAKER_TOKEN, MAKER_TOKEN])
.callAsync();
expect(quotes).to.deep.eq(expectedQuotes);
});
@@ -811,12 +834,9 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
const intermediateToken = randomAddress();
const sampleAmounts = getSampleAmounts(MAKER_TOKEN);
const expectedQuotes = predictBuyQuotes([TAKER_TOKEN, intermediateToken, MAKER_TOKEN], sampleAmounts);
await testContract.setSampleValues(sampleAmounts).awaitTransactionSuccessAsync();
const quotes = await testContract
.sampleBuysFromUniswapV2(
UNISWAP_V2_ROUTER,
[TAKER_TOKEN, intermediateToken, MAKER_TOKEN],
sampleAmounts,
)
.sampleBuysFromUniswapV2Global(UNISWAP_V2_ROUTER, [TAKER_TOKEN, intermediateToken, MAKER_TOKEN])
.callAsync();
expect(quotes).to.deep.eq(expectedQuotes);
});
@@ -920,13 +940,15 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
// tslint:disable-next-line no-unnecessary-type-assertion
const sellAmount = _.last(getSampleAmounts(TAKER_TOKEN))!;
const uniswapV2FirstHopPath = [TAKER_TOKEN, INTERMEDIATE_TOKEN];
await testContract.setSampleValues([sellAmount]).callAsync();
const uniswapV2FirstHop = testContract
.sampleSellsFromUniswapV2(UNISWAP_V2_ROUTER, uniswapV2FirstHopPath, [constants.ZERO_AMOUNT])
.sampleSellsFromUniswapV2Global(UNISWAP_V2_ROUTER, uniswapV2FirstHopPath)
.getABIEncodedTransactionData();
const uniswapV2SecondHopPath = [INTERMEDIATE_TOKEN, randomAddress(), MAKER_TOKEN];
const uniswapV2SecondHop = testContract
.sampleSellsFromUniswapV2(UNISWAP_V2_ROUTER, uniswapV2SecondHopPath, [constants.ZERO_AMOUNT])
.sampleSellsFromUniswapV2Global(UNISWAP_V2_ROUTER, uniswapV2SecondHopPath)
.getABIEncodedTransactionData();
const firstHopQuotes = [getDeterministicUniswapV2SellQuote(uniswapV2FirstHopPath, sellAmount)];
@@ -951,13 +973,15 @@ blockchainTests.skip('erc20-bridge-sampler', env => {
// tslint:disable-next-line no-unnecessary-type-assertion
const buyAmount = _.last(getSampleAmounts(MAKER_TOKEN))!;
const uniswapV2FirstHopPath = [TAKER_TOKEN, INTERMEDIATE_TOKEN];
await testContract.setSampleValues([buyAmount]).callAsync();
const uniswapV2FirstHop = testContract
.sampleBuysFromUniswapV2(UNISWAP_V2_ROUTER, uniswapV2FirstHopPath, [constants.ZERO_AMOUNT])
.sampleBuysFromUniswapV2Global(UNISWAP_V2_ROUTER, uniswapV2FirstHopPath)
.getABIEncodedTransactionData();
const uniswapV2SecondHopPath = [INTERMEDIATE_TOKEN, randomAddress(), MAKER_TOKEN];
const uniswapV2SecondHop = testContract
.sampleBuysFromUniswapV2(UNISWAP_V2_ROUTER, uniswapV2SecondHopPath, [constants.ZERO_AMOUNT])
.sampleBuysFromUniswapV2Global(UNISWAP_V2_ROUTER, uniswapV2SecondHopPath)
.getABIEncodedTransactionData();
const secondHopQuotes = [getDeterministicUniswapV2BuyQuote(uniswapV2SecondHopPath, buyAmount)];

View File

@@ -148,10 +148,9 @@ describe('DexSampler tests', () => {
const expectedTakerFillAmounts = getSampleAmounts(new BigNumber(100e18), 10);
const expectedMakerFillAmounts = getSampleAmounts(new BigNumber(100e18), 10);
const sampler = new MockSamplerContract({
sampleSellsFromKyberNetwork: (_reserveOffset, takerToken, makerToken, fillAmounts) => {
sampleSellsFromKyberNetworkGlobal: (_reserveOffset, takerToken, makerToken) => {
expect(takerToken).to.eq(expectedTakerToken);
expect(makerToken).to.eq(expectedMakerToken);
expect(fillAmounts).to.deep.eq(expectedTakerFillAmounts);
return ['0x', '0x', expectedMakerFillAmounts];
},
});
@@ -182,7 +181,7 @@ describe('DexSampler tests', () => {
const poolAddress = randomAddress();
const gasCost = 123;
const sampler = new MockSamplerContract({
sampleSellsFromLiquidityProvider: (providerAddress, takerToken, makerToken, _fillAmounts) => {
sampleSellsFromLiquidityProviderGlobal: (providerAddress, takerToken, makerToken) => {
expect(providerAddress).to.eq(poolAddress);
expect(takerToken).to.eq(expectedTakerToken);
expect(makerToken).to.eq(expectedMakerToken);
@@ -226,7 +225,7 @@ describe('DexSampler tests', () => {
const poolAddress = randomAddress();
const gasCost = 321;
const sampler = new MockSamplerContract({
sampleBuysFromLiquidityProvider: (providerAddress, takerToken, makerToken, _fillAmounts) => {
sampleBuysFromLiquidityProviderGlobal: (providerAddress, takerToken, makerToken) => {
expect(providerAddress).to.eq(poolAddress);
expect(takerToken).to.eq(expectedTakerToken);
expect(makerToken).to.eq(expectedMakerToken);
@@ -270,10 +269,9 @@ describe('DexSampler tests', () => {
const expectedTakerFillAmounts = getSampleAmounts(new BigNumber(100e18), 10);
const expectedMakerFillAmounts = getSampleAmounts(new BigNumber(100e18), 10);
const sampler = new MockSamplerContract({
sampleSellsFromUniswap: (_router, takerToken, makerToken, fillAmounts) => {
sampleSellsFromUniswapGlobal: (_router, takerToken, makerToken) => {
expect(takerToken).to.eq(expectedTakerToken);
expect(makerToken).to.eq(expectedMakerToken);
expect(fillAmounts).to.deep.eq(expectedTakerFillAmounts);
return expectedMakerFillAmounts;
},
});
@@ -303,9 +301,8 @@ describe('DexSampler tests', () => {
const expectedTakerFillAmounts = getSampleAmounts(new BigNumber(100e18), 10);
const expectedMakerFillAmounts = getSampleAmounts(new BigNumber(100e18), 10);
const sampler = new MockSamplerContract({
sampleSellsFromUniswapV2: (_router, path, fillAmounts) => {
sampleSellsFromUniswapV2Global: (_router, path) => {
expect(path).to.deep.eq([expectedMakerToken, expectedTakerToken]);
expect(fillAmounts).to.deep.eq(expectedTakerFillAmounts);
return expectedMakerFillAmounts;
},
});
@@ -334,10 +331,9 @@ describe('DexSampler tests', () => {
const expectedTakerFillAmounts = getSampleAmounts(new BigNumber(100e18), 10);
const expectedMakerFillAmounts = getSampleAmounts(new BigNumber(100e18), 10);
const sampler = new MockSamplerContract({
sampleBuysFromUniswap: (_router, takerToken, makerToken, fillAmounts) => {
sampleBuysFromUniswapGlobal: (_router, takerToken, makerToken) => {
expect(takerToken).to.eq(expectedTakerToken);
expect(makerToken).to.eq(expectedMakerToken);
expect(fillAmounts).to.deep.eq(expectedMakerFillAmounts);
return expectedTakerFillAmounts;
},
});
@@ -378,14 +374,15 @@ describe('DexSampler tests', () => {
let uniswapRouter: string;
let uniswapV2Router: string;
const sampler = new MockSamplerContract({
sampleSellsFromUniswap: (router, takerToken, makerToken, fillAmounts) => {
sampleSellsFromUniswapGlobal: (router, takerToken, makerToken) => {
uniswapRouter = router;
expect(takerToken).to.eq(expectedTakerToken);
expect(makerToken).to.eq(expectedMakerToken);
expect(fillAmounts).to.deep.eq(expectedTakerFillAmounts);
return fillAmounts.map(a => a.times(ratesBySource[ERC20BridgeSource.Uniswap]).integerValue());
return expectedTakerFillAmounts.map(a =>
a.times(ratesBySource[ERC20BridgeSource.Uniswap]).integerValue(),
);
},
sampleSellsFromUniswapV2: (router, path, fillAmounts) => {
sampleSellsFromUniswapV2Global: (router, path) => {
uniswapV2Router = router;
if (path.length === 2) {
expect(path).to.deep.eq([expectedTakerToken, expectedMakerToken]);
@@ -394,8 +391,9 @@ describe('DexSampler tests', () => {
} else {
expect(path).to.have.lengthOf.within(2, 3);
}
expect(fillAmounts).to.deep.eq(expectedTakerFillAmounts);
return fillAmounts.map(a => a.times(ratesBySource[ERC20BridgeSource.UniswapV2]).integerValue());
return expectedTakerFillAmounts.map(a =>
a.times(ratesBySource[ERC20BridgeSource.UniswapV2]).integerValue(),
);
},
});
const dexOrderSampler = new DexOrderSampler(
@@ -463,14 +461,15 @@ describe('DexSampler tests', () => {
let uniswapRouter: string;
let uniswapV2Router: string;
const sampler = new MockSamplerContract({
sampleBuysFromUniswap: (router, takerToken, makerToken, fillAmounts) => {
sampleBuysFromUniswapGlobal: (router, takerToken, makerToken) => {
uniswapRouter = router;
expect(takerToken).to.eq(expectedTakerToken);
expect(makerToken).to.eq(expectedMakerToken);
expect(fillAmounts).to.deep.eq(expectedMakerFillAmounts);
return fillAmounts.map(a => a.times(ratesBySource[ERC20BridgeSource.Uniswap]).integerValue());
return expectedMakerFillAmounts.map(a =>
a.times(ratesBySource[ERC20BridgeSource.Uniswap]).integerValue(),
);
},
sampleBuysFromUniswapV2: (router, path, fillAmounts) => {
sampleBuysFromUniswapV2Global: (router, path) => {
uniswapV2Router = router;
if (path.length === 2) {
expect(path).to.deep.eq([expectedTakerToken, expectedMakerToken]);
@@ -479,8 +478,9 @@ describe('DexSampler tests', () => {
} else {
expect(path).to.have.lengthOf.within(2, 3);
}
expect(fillAmounts).to.deep.eq(expectedMakerFillAmounts);
return fillAmounts.map(a => a.times(ratesBySource[ERC20BridgeSource.UniswapV2]).integerValue());
return expectedMakerFillAmounts.map(a =>
a.times(ratesBySource[ERC20BridgeSource.UniswapV2]).integerValue(),
);
},
});
const dexOrderSampler = new DexOrderSampler(

View File

@@ -430,6 +430,8 @@ describe('MarketOperationUtils tests', () => {
isAddressContract: (..._params: any[]) => false,
getGasLeft: () => ZERO_AMOUNT,
getBlockNumber: () => ZERO_AMOUNT,
// tslint:disable-next-line:no-empty
setSampleValues: () => {},
};
const MOCK_SAMPLER = ({

View File

@@ -15,51 +15,24 @@ export type GetOrderFillableAssetAmountHandler = (
) => GetOrderFillableAssetAmountResult;
export type SampleResults = BigNumber[];
export type SampleSellsUniswapHandler = (
router: string,
takerToken: string,
makerToken: string,
takerTokenAmounts: BigNumber[],
) => SampleResults;
export type SampleBuysUniswapHandler = (
router: string,
takerToken: string,
makerToken: string,
makerTokenAmounts: BigNumber[],
) => SampleResults;
export type SampleSellsEth2DaiHandler = (
router: string,
takerToken: string,
makerToken: string,
takerTokenAmounts: BigNumber[],
) => SampleResults;
export type SampleBuysEth2DaiHandler = (
router: string,
takerToken: string,
makerToken: string,
makerTokenAmounts: BigNumber[],
) => SampleResults;
export type SampleSellsUniswapHandler = (router: string, takerToken: string, makerToken: string) => SampleResults;
export type SampleBuysUniswapHandler = (router: string, takerToken: string, makerToken: string) => SampleResults;
export type SampleSellsEth2DaiHandler = (router: string, takerToken: string, makerToken: string) => SampleResults;
export type SampleBuysEth2DaiHandler = (router: string, takerToken: string, makerToken: string) => SampleResults;
export type SampleSellsKyberHandler = (
opts: KyberSamplerOpts,
takerToken: string,
makerToken: string,
takerTokenAmounts: BigNumber[],
) => [string, string, SampleResults];
export type SampleBuysKyberHandler = (
reserveId: string,
takerToken: string,
makerToken: string,
makerTokenAmounts: BigNumber[],
) => [string, SampleResults];
export type SampleUniswapV2Handler = (router: string, path: string[], assetAmounts: BigNumber[]) => SampleResults;
export type SampleBuysMultihopHandler = (path: string[], takerTokenAmounts: BigNumber[]) => SampleResults;
export type SampleSellsLPHandler = (
providerAddress: string,
takerToken: string,
makerToken: string,
takerTokenAmounts: BigNumber[],
) => SampleResults;
export type SampleSellsMultihopHandler = (path: string[], takerTokenAmounts: BigNumber[]) => SampleResults;
export type SampleUniswapV2Handler = (router: string, path: string[]) => SampleResults;
export type SampleBuysMultihopHandler = (path: string[]) => SampleResults;
export type SampleSellsLPHandler = (providerAddress: string, takerToken: string, makerToken: string) => SampleResults;
export type SampleSellsMultihopHandler = (path: string[]) => SampleResults;
const DUMMY_PROVIDER = {
sendAsync: (..._args: any[]): any => {
@@ -70,13 +43,13 @@ const DUMMY_PROVIDER = {
interface Handlers {
getLimitOrderFillableMakerAssetAmounts: GetOrderFillableAssetAmountHandler;
getLimitOrderFillableTakerAssetAmounts: GetOrderFillableAssetAmountHandler;
sampleSellsFromKyberNetwork: SampleSellsKyberHandler;
sampleSellsFromLiquidityProvider: SampleSellsLPHandler;
sampleSellsFromUniswap: SampleSellsUniswapHandler;
sampleSellsFromUniswapV2: SampleUniswapV2Handler;
sampleBuysFromUniswap: SampleBuysUniswapHandler;
sampleBuysFromUniswapV2: SampleUniswapV2Handler;
sampleBuysFromLiquidityProvider: SampleSellsLPHandler;
sampleSellsFromKyberNetworkGlobal: SampleSellsKyberHandler;
sampleSellsFromLiquidityProviderGlobal: SampleSellsLPHandler;
sampleSellsFromUniswapGlobal: SampleSellsUniswapHandler;
sampleSellsFromUniswapV2Global: SampleUniswapV2Handler;
sampleBuysFromUniswapGlobal: SampleBuysUniswapHandler;
sampleBuysFromUniswapV2Global: SampleUniswapV2Handler;
sampleBuysFromLiquidityProviderGlobal: SampleSellsLPHandler;
}
// tslint:disable: no-unbound-method
@@ -130,12 +103,11 @@ export class MockSamplerContract extends ERC20BridgeSamplerContract {
takerAssetAmounts: BigNumber[],
): ContractTxFunctionObj<[string, string, BigNumber[]]> {
return this._wrapCall(
super.sampleSellsFromKyberNetwork,
this._handlers.sampleSellsFromKyberNetwork,
super.sampleSellsFromKyberNetworkGlobal,
this._handlers.sampleSellsFromKyberNetworkGlobal,
{ ...opts, reserveOffset: new BigNumber(1), hint: NULL_BYTES },
takerToken,
makerToken,
takerAssetAmounts,
);
}
@@ -146,12 +118,11 @@ export class MockSamplerContract extends ERC20BridgeSamplerContract {
takerAssetAmounts: BigNumber[],
): ContractTxFunctionObj<BigNumber[]> {
return this._wrapCall(
super.sampleSellsFromUniswap,
this._handlers.sampleSellsFromUniswap,
super.sampleSellsFromUniswapGlobal,
this._handlers.sampleSellsFromUniswapGlobal,
router,
takerToken,
makerToken,
takerAssetAmounts,
);
}
@@ -161,11 +132,10 @@ export class MockSamplerContract extends ERC20BridgeSamplerContract {
takerAssetAmounts: BigNumber[],
): ContractTxFunctionObj<BigNumber[]> {
return this._wrapCall(
super.sampleSellsFromUniswapV2,
this._handlers.sampleSellsFromUniswapV2,
super.sampleSellsFromUniswapV2Global,
this._handlers.sampleSellsFromUniswapV2Global,
router,
path,
takerAssetAmounts,
);
}
@@ -176,12 +146,11 @@ export class MockSamplerContract extends ERC20BridgeSamplerContract {
takerAssetAmounts: BigNumber[],
): ContractTxFunctionObj<BigNumber[]> {
return this._wrapCall(
super.sampleSellsFromLiquidityProvider,
this._handlers.sampleSellsFromLiquidityProvider,
super.sampleSellsFromLiquidityProviderGlobal,
this._handlers.sampleSellsFromLiquidityProviderGlobal,
providerAddress,
takerToken,
makerToken,
takerAssetAmounts,
);
}
@@ -192,12 +161,11 @@ export class MockSamplerContract extends ERC20BridgeSamplerContract {
makerAssetAmounts: BigNumber[],
): ContractTxFunctionObj<BigNumber[]> {
return this._wrapCall(
super.sampleBuysFromUniswap,
this._handlers.sampleBuysFromUniswap,
super.sampleBuysFromUniswapGlobal,
this._handlers.sampleBuysFromUniswapGlobal,
router,
takerToken,
makerToken,
makerAssetAmounts,
);
}
@@ -207,11 +175,10 @@ export class MockSamplerContract extends ERC20BridgeSamplerContract {
makerAssetAmounts: BigNumber[],
): ContractTxFunctionObj<BigNumber[]> {
return this._wrapCall(
super.sampleBuysFromUniswapV2,
this._handlers.sampleBuysFromUniswapV2,
super.sampleBuysFromUniswapV2Global,
this._handlers.sampleBuysFromUniswapV2Global,
router,
path,
makerAssetAmounts,
);
}

View File

@@ -10,15 +10,19 @@ export * from '../test/generated-wrappers/balancer_v2_sampler';
export * from '../test/generated-wrappers/bancor_sampler';
export * from '../test/generated-wrappers/compound_sampler';
export * from '../test/generated-wrappers/curve_sampler';
export * from '../test/generated-wrappers/curve_sampler_test';
export * from '../test/generated-wrappers/d_o_d_o_sampler';
export * from '../test/generated-wrappers/d_o_d_o_v2_sampler';
export * from '../test/generated-wrappers/d_s_test';
export * from '../test/generated-wrappers/dummy_liquidity_provider';
export * from '../test/generated-wrappers/erc20_bridge_sampler';
export * from '../test/generated-wrappers/fake_taker';
export * from '../test/generated-wrappers/i_balancer';
export * from '../test/generated-wrappers/i_bancor';
export * from '../test/generated-wrappers/i_curve';
export * from '../test/generated-wrappers/i_erc20_token_v06';
export * from '../test/generated-wrappers/i_kyber_network';
export * from '../test/generated-wrappers/i_liquidity_provider';
export * from '../test/generated-wrappers/i_m_stable';
export * from '../test/generated-wrappers/i_mooniswap';
export * from '../test/generated-wrappers/i_multi_bridge';
@@ -28,6 +32,8 @@ export * from '../test/generated-wrappers/i_uniswap_exchange_quotes';
export * from '../test/generated-wrappers/i_uniswap_v2_router01';
export * from '../test/generated-wrappers/kyber_dmm_sampler';
export * from '../test/generated-wrappers/kyber_sampler';
export * from '../test/generated-wrappers/lib_bytes';
export * from '../test/generated-wrappers/lib_safe_math';
export * from '../test/generated-wrappers/lido_sampler';
export * from '../test/generated-wrappers/liquidity_provider_sampler';
export * from '../test/generated-wrappers/m_stable_sampler';
@@ -35,13 +41,16 @@ export * from '../test/generated-wrappers/maker_p_s_m_sampler';
export * from '../test/generated-wrappers/mooniswap_sampler';
export * from '../test/generated-wrappers/multi_bridge_sampler';
export * from '../test/generated-wrappers/native_order_sampler';
export * from '../test/generated-wrappers/sampler_base';
export * from '../test/generated-wrappers/sampler_utils';
export * from '../test/generated-wrappers/shell_sampler';
export * from '../test/generated-wrappers/smoothy_sampler';
export * from '../test/generated-wrappers/test_base';
export * from '../test/generated-wrappers/test_erc20_bridge_sampler';
export * from '../test/generated-wrappers/test_native_order_sampler';
export * from '../test/generated-wrappers/two_hop_sampler';
export * from '../test/generated-wrappers/uniswap_sampler';
export * from '../test/generated-wrappers/uniswap_v2_sampler';
export * from '../test/generated-wrappers/uniswap_v2_sampler_test';
export * from '../test/generated-wrappers/uniswap_v3_sampler';
export * from '../test/generated-wrappers/utility_sampler';

View File

@@ -15,13 +15,16 @@
"test/generated-artifacts/CurveSampler.json",
"test/generated-artifacts/DODOSampler.json",
"test/generated-artifacts/DODOV2Sampler.json",
"test/generated-artifacts/DSTest.json",
"test/generated-artifacts/DummyLiquidityProvider.json",
"test/generated-artifacts/ERC20BridgeSampler.json",
"test/generated-artifacts/FakeTaker.json",
"test/generated-artifacts/IBalancer.json",
"test/generated-artifacts/IBancor.json",
"test/generated-artifacts/ICurve.json",
"test/generated-artifacts/IERC20TokenV06.json",
"test/generated-artifacts/IKyberNetwork.json",
"test/generated-artifacts/ILiquidityProvider.json",
"test/generated-artifacts/IMStable.json",
"test/generated-artifacts/IMooniswap.json",
"test/generated-artifacts/IMultiBridge.json",
@@ -31,6 +34,8 @@
"test/generated-artifacts/IUniswapV2Router01.json",
"test/generated-artifacts/KyberDmmSampler.json",
"test/generated-artifacts/KyberSampler.json",
"test/generated-artifacts/LibBytes.json",
"test/generated-artifacts/LibSafeMath.json",
"test/generated-artifacts/LidoSampler.json",
"test/generated-artifacts/LiquidityProviderSampler.json",
"test/generated-artifacts/MStableSampler.json",
@@ -38,14 +43,17 @@
"test/generated-artifacts/MooniswapSampler.json",
"test/generated-artifacts/MultiBridgeSampler.json",
"test/generated-artifacts/NativeOrderSampler.json",
"test/generated-artifacts/SamplerBase.json",
"test/generated-artifacts/SamplerUtils.json",
"test/generated-artifacts/ShellSampler.json",
"test/generated-artifacts/SmoothySampler.json",
"test/generated-artifacts/TestBase.json",
"test/generated-artifacts/TestERC20BridgeSampler.json",
"test/generated-artifacts/TestNativeOrderSampler.json",
"test/generated-artifacts/TwoHopSampler.json",
"test/generated-artifacts/UniswapSampler.json",
"test/generated-artifacts/UniswapV2Sampler.json",
"test/generated-artifacts/UniswapV2SamplerTest.json",
"test/generated-artifacts/UniswapV3Sampler.json",
"test/generated-artifacts/UtilitySampler.json"
]