Maker PSM integration [TKR-2] (#150)
* ADDS basic boilerplate for PSM bridge WIP * ADDS integrate the MakerPSM mixin and fix incorrect naming * fix: take into account PSM fee when buying USDC from PSM * feat: intial stab at a PSM sampler WIP * feat: integrate MakerPsm into AS WIP * refactor: get VAT contract address from PSM instead of passing it in * fix: hardcode PSM Gemtoken to USDC * fix: remove passing in authGem, get from PSM contract instead * fix: use constant modified to avoid using storage variables * fix: incorrect num decimals after multiplication in sampler * fix: PSM buy sampling * fix: use fillData to estimate gas schedule * Rebased on latest development * Guard and use latest Curve LiquidityProvider * `@0x/contract-addresses`: Redeploy FQT on mainnet and ropsten Co-authored-by: Jacob Evans <jacob@dekz.net> Co-authored-by: Lawrence Forman <lawrence@0xproject.com>
This commit is contained in:
@@ -30,6 +30,7 @@ import "./mixins/MixinCryptoCom.sol";
|
||||
import "./mixins/MixinDodo.sol";
|
||||
import "./mixins/MixinDodoV2.sol";
|
||||
import "./mixins/MixinKyber.sol";
|
||||
import "./mixins/MixinMakerPSM.sol";
|
||||
import "./mixins/MixinMooniswap.sol";
|
||||
import "./mixins/MixinMStable.sol";
|
||||
import "./mixins/MixinNerve.sol";
|
||||
@@ -49,6 +50,7 @@ contract BridgeAdapter is
|
||||
MixinDodo,
|
||||
MixinDodoV2,
|
||||
MixinKyber,
|
||||
MixinMakerPSM,
|
||||
MixinMooniswap,
|
||||
MixinMStable,
|
||||
MixinNerve,
|
||||
@@ -68,6 +70,7 @@ contract BridgeAdapter is
|
||||
MixinDodo()
|
||||
MixinDodoV2()
|
||||
MixinKyber(weth)
|
||||
MixinMakerPSM()
|
||||
MixinMooniswap(weth)
|
||||
MixinMStable()
|
||||
MixinNerve()
|
||||
@@ -123,6 +126,13 @@ contract BridgeAdapter is
|
||||
sellAmount,
|
||||
order.bridgeData
|
||||
);
|
||||
} else if (protocolId == BridgeProtocols.MAKERPSM) {
|
||||
boughtAmount = _tradeMakerPsm(
|
||||
sellToken,
|
||||
buyToken,
|
||||
sellAmount,
|
||||
order.bridgeData
|
||||
);
|
||||
} else if (protocolId == BridgeProtocols.MOONISWAP) {
|
||||
boughtAmount = _tradeMooniswap(
|
||||
sellToken,
|
||||
|
||||
@@ -43,4 +43,5 @@ library BridgeProtocols {
|
||||
uint128 internal constant BANCOR = 13;
|
||||
uint128 internal constant COFIX = 14;
|
||||
uint128 internal constant NERVE = 15;
|
||||
uint128 internal constant MAKERPSM = 16;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
// 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.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
|
||||
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
|
||||
|
||||
interface IPSM {
|
||||
// @dev Get the fee for selling USDC to DAI in PSM
|
||||
// @return tin toll in [wad]
|
||||
function tin() external view returns (uint256);
|
||||
// @dev Get the fee for selling DAI to USDC in PSM
|
||||
// @return tout toll out [wad]
|
||||
function tout() external view returns (uint256);
|
||||
|
||||
// @dev Get the address of the PSM state Vat
|
||||
// @return address of the Vat
|
||||
function vat() external view returns (address);
|
||||
|
||||
// @dev Get the address of the underlying vault powering PSM
|
||||
// @return address of gemJoin contract
|
||||
function gemJoin() external view returns (address);
|
||||
|
||||
// @dev Sell USDC for DAI
|
||||
// @param usr The address of the account trading USDC for DAI.
|
||||
// @param gemAmt The amount of USDC to sell in USDC base units
|
||||
function sellGem(
|
||||
address usr,
|
||||
uint256 gemAmt
|
||||
) external;
|
||||
// @dev Buy USDC for DAI
|
||||
// @param usr The address of the account trading DAI for USDC
|
||||
// @param gemAmt The amount of USDC to buy in USDC base units
|
||||
function buyGem(
|
||||
address usr,
|
||||
uint256 gemAmt
|
||||
) external;
|
||||
}
|
||||
|
||||
contract MixinMakerPSM {
|
||||
|
||||
using LibERC20TokenV06 for IERC20TokenV06;
|
||||
using LibSafeMathV06 for uint256;
|
||||
|
||||
struct MakerPsmBridgeData {
|
||||
address psmAddress;
|
||||
address gemTokenAddres;
|
||||
}
|
||||
|
||||
// Maker units
|
||||
// wad: fixed point decimal with 18 decimals (for basic quantities, e.g. balances)
|
||||
uint256 constant private WAD = 10 ** 18;
|
||||
// ray: fixed point decimal with 27 decimals (for precise quantites, e.g. ratios)
|
||||
uint256 constant private RAY = 10 ** 27;
|
||||
// rad: fixed point decimal with 45 decimals (result of integer multiplication with a wad and a ray)
|
||||
uint256 constant private RAD = 10 ** 45;
|
||||
// See https://github.com/makerdao/dss/blob/master/DEVELOPING.md
|
||||
|
||||
function _tradeMakerPsm(
|
||||
IERC20TokenV06 sellToken,
|
||||
IERC20TokenV06 buyToken,
|
||||
uint256 sellAmount,
|
||||
bytes memory bridgeData
|
||||
)
|
||||
internal
|
||||
returns (uint256 boughtAmount)
|
||||
{
|
||||
// Decode the bridge data.
|
||||
MakerPsmBridgeData memory data = abi.decode(bridgeData, (MakerPsmBridgeData));
|
||||
uint256 beforeBalance = buyToken.balanceOf(address(this));
|
||||
|
||||
IPSM psm = IPSM(data.psmAddress);
|
||||
|
||||
if (address(sellToken) == data.gemTokenAddres) {
|
||||
sellToken.approveIfBelow(
|
||||
psm.gemJoin(),
|
||||
sellAmount
|
||||
);
|
||||
|
||||
psm.sellGem(address(this), sellAmount);
|
||||
} else if (address(buyToken) == data.gemTokenAddres) {
|
||||
uint256 feeDivisor = WAD.safeAdd(psm.tout()); // eg. 1.001 * 10 ** 18 with 0.1% fee [tout is in wad];
|
||||
uint256 buyTokenBaseUnit = uint256(10) ** uint256(buyToken.decimals());
|
||||
uint256 gemAmount = sellAmount.safeMul(buyTokenBaseUnit).safeDiv(feeDivisor);
|
||||
|
||||
sellToken.approveIfBelow(
|
||||
data.psmAddress,
|
||||
sellAmount
|
||||
);
|
||||
psm.buyGem(address(this), gemAmount);
|
||||
}
|
||||
|
||||
return buyToken.balanceOf(address(this)).safeSub(beforeBalance);
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,7 @@
|
||||
"config": {
|
||||
"publicInterfaceContracts": "IZeroEx,ZeroEx,FullMigration,InitialMigration,IFlashWallet,IERC20Transformer,IOwnableFeature,ISimpleFunctionRegistryFeature,ITransformERC20Feature,FillQuoteTransformer,PayTakerTransformer,PositiveSlippageFeeTransformer,WethTransformer,OwnableFeature,SimpleFunctionRegistryFeature,TransformERC20Feature,AffiliateFeeTransformer,MetaTransactionsFeature,LogMetadataTransformer,BridgeAdapter,LiquidityProviderFeature,ILiquidityProviderFeature,NativeOrdersFeature,INativeOrdersFeature,FeeCollectorController,FeeCollector,CurveLiquidityProvider,BatchFillNativeOrdersFeature,IBatchFillNativeOrdersFeature,MultiplexFeature,IMultiplexFeature",
|
||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
|
||||
"abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeAdapter|BridgeProtocols|CurveLiquidityProvider|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC20Bridge|IERC20Transformer|IFeature|IFlashWallet|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOwnableFeature|IPancakeSwapFeature|ISimpleFunctionRegistryFeature|IStaking|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC20Transformer|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinBalancer|MixinBancor|MixinCoFiX|MixinCryptoCom|MixinCurve|MixinDodo|MixinDodoV2|MixinKyber|MixinMStable|MixinMooniswap|MixinNerve|MixinOasis|MixinShell|MixinUniswap|MixinUniswapV2|MixinZeroExBridge|MooniswapLiquidityProvider|MultiplexFeature|NativeOrdersCancellation|NativeOrdersFeature|NativeOrdersInfo|NativeOrdersProtocolFees|NativeOrdersSettlement|OwnableFeature|PancakeSwapFeature|PayTakerTransformer|PermissionlessTransformerDeployer|PositiveSlippageFeeTransformer|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestCurve|TestDelegateCaller|TestFeeCollectorController|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC20Token|TestMooniswap|TestNativeOrdersFeature|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestWeth|TestWethTransformerHost|TestZeroExFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|WethTransformer|ZeroEx|ZeroExOptimized).json"
|
||||
"abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeAdapter|BridgeProtocols|CurveLiquidityProvider|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC20Bridge|IERC20Transformer|IFeature|IFlashWallet|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOwnableFeature|IPancakeSwapFeature|ISimpleFunctionRegistryFeature|IStaking|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC20Transformer|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinBalancer|MixinBancor|MixinCoFiX|MixinCryptoCom|MixinCurve|MixinDodo|MixinDodoV2|MixinKyber|MixinMStable|MixinMakerPSM|MixinMooniswap|MixinNerve|MixinOasis|MixinShell|MixinUniswap|MixinUniswapV2|MixinZeroExBridge|MooniswapLiquidityProvider|MultiplexFeature|NativeOrdersCancellation|NativeOrdersFeature|NativeOrdersInfo|NativeOrdersProtocolFees|NativeOrdersSettlement|OwnableFeature|PancakeSwapFeature|PayTakerTransformer|PermissionlessTransformerDeployer|PositiveSlippageFeeTransformer|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestCurve|TestDelegateCaller|TestFeeCollectorController|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC20Token|TestMooniswap|TestNativeOrdersFeature|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestWeth|TestWethTransformerHost|TestZeroExFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|WethTransformer|ZeroEx|ZeroExOptimized).json"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -13,7 +13,6 @@ import * as FeeCollector from '../generated-artifacts/FeeCollector.json';
|
||||
import * as FeeCollectorController from '../generated-artifacts/FeeCollectorController.json';
|
||||
import * as FillQuoteTransformer from '../generated-artifacts/FillQuoteTransformer.json';
|
||||
import * as FullMigration from '../generated-artifacts/FullMigration.json';
|
||||
import * as IAllowanceTarget from '../generated-artifacts/IAllowanceTarget.json';
|
||||
import * as IBatchFillNativeOrdersFeature from '../generated-artifacts/IBatchFillNativeOrdersFeature.json';
|
||||
import * as IERC20Transformer from '../generated-artifacts/IERC20Transformer.json';
|
||||
import * as IFlashWallet from '../generated-artifacts/IFlashWallet.json';
|
||||
@@ -43,7 +42,6 @@ export const artifacts = {
|
||||
FullMigration: FullMigration as ContractArtifact,
|
||||
InitialMigration: InitialMigration as ContractArtifact,
|
||||
IFlashWallet: IFlashWallet as ContractArtifact,
|
||||
IAllowanceTarget: IAllowanceTarget as ContractArtifact,
|
||||
IERC20Transformer: IERC20Transformer as ContractArtifact,
|
||||
IOwnableFeature: IOwnableFeature as ContractArtifact,
|
||||
ISimpleFunctionRegistryFeature: ISimpleFunctionRegistryFeature as ContractArtifact,
|
||||
|
||||
@@ -11,7 +11,6 @@ export * from '../generated-wrappers/fee_collector';
|
||||
export * from '../generated-wrappers/fee_collector_controller';
|
||||
export * from '../generated-wrappers/fill_quote_transformer';
|
||||
export * from '../generated-wrappers/full_migration';
|
||||
export * from '../generated-wrappers/i_allowance_target';
|
||||
export * from '../generated-wrappers/i_batch_fill_native_orders_feature';
|
||||
export * from '../generated-wrappers/i_erc20_transformer';
|
||||
export * from '../generated-wrappers/i_flash_wallet';
|
||||
|
||||
@@ -83,6 +83,7 @@ import * as MixinCurve from '../test/generated-artifacts/MixinCurve.json';
|
||||
import * as MixinDodo from '../test/generated-artifacts/MixinDodo.json';
|
||||
import * as MixinDodoV2 from '../test/generated-artifacts/MixinDodoV2.json';
|
||||
import * as MixinKyber from '../test/generated-artifacts/MixinKyber.json';
|
||||
import * as MixinMakerPSM from '../test/generated-artifacts/MixinMakerPSM.json';
|
||||
import * as MixinMooniswap from '../test/generated-artifacts/MixinMooniswap.json';
|
||||
import * as MixinMStable from '../test/generated-artifacts/MixinMStable.json';
|
||||
import * as MixinNerve from '../test/generated-artifacts/MixinNerve.json';
|
||||
@@ -241,6 +242,7 @@ export const artifacts = {
|
||||
MixinDodoV2: MixinDodoV2 as ContractArtifact,
|
||||
MixinKyber: MixinKyber as ContractArtifact,
|
||||
MixinMStable: MixinMStable as ContractArtifact,
|
||||
MixinMakerPSM: MixinMakerPSM as ContractArtifact,
|
||||
MixinMooniswap: MixinMooniswap as ContractArtifact,
|
||||
MixinNerve: MixinNerve as ContractArtifact,
|
||||
MixinOasis: MixinOasis as ContractArtifact,
|
||||
|
||||
@@ -82,6 +82,7 @@ export * from '../test/generated-wrappers/mixin_dodo';
|
||||
export * from '../test/generated-wrappers/mixin_dodo_v2';
|
||||
export * from '../test/generated-wrappers/mixin_kyber';
|
||||
export * from '../test/generated-wrappers/mixin_m_stable';
|
||||
export * from '../test/generated-wrappers/mixin_maker_p_s_m';
|
||||
export * from '../test/generated-wrappers/mixin_mooniswap';
|
||||
export * from '../test/generated-wrappers/mixin_nerve';
|
||||
export * from '../test/generated-wrappers/mixin_oasis';
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
"generated-artifacts/FeeCollectorController.json",
|
||||
"generated-artifacts/FillQuoteTransformer.json",
|
||||
"generated-artifacts/FullMigration.json",
|
||||
"generated-artifacts/IAllowanceTarget.json",
|
||||
"generated-artifacts/IBatchFillNativeOrdersFeature.json",
|
||||
"generated-artifacts/IERC20Transformer.json",
|
||||
"generated-artifacts/IFlashWallet.json",
|
||||
@@ -114,6 +113,7 @@
|
||||
"test/generated-artifacts/MixinDodoV2.json",
|
||||
"test/generated-artifacts/MixinKyber.json",
|
||||
"test/generated-artifacts/MixinMStable.json",
|
||||
"test/generated-artifacts/MixinMakerPSM.json",
|
||||
"test/generated-artifacts/MixinMooniswap.json",
|
||||
"test/generated-artifacts/MixinNerve.json",
|
||||
"test/generated-artifacts/MixinOasis.json",
|
||||
|
||||
Reference in New Issue
Block a user