add weth/eth wrap/unwrap support for bancorv3

This commit is contained in:
Noah Khamliche 2022-06-02 20:14:02 -04:00 committed by Noah Khamliche
parent f5c486050b
commit 9b131199ad
5 changed files with 56 additions and 14 deletions

View File

@ -75,6 +75,7 @@ contract EthereumBridgeAdapter is
constructor(IEtherTokenV06 weth)
public
MixinBancor(weth)
MixinBancorV3(weth)
MixinCompound(weth)
MixinCurve(weth)
MixinLido(weth)

View File

@ -23,6 +23,8 @@ pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
/*
BancorV3
@ -42,25 +44,37 @@ interface IBancorV3 {
uint256 minReturnAmount,
uint256 deadline,
address beneficiary
) external returns (uint256 amount);
) external payable returns (uint256 amount);
}
contract MixinBancorV3 {
using LibERC20TokenV06 for IERC20TokenV06;
IERC20TokenV06 constant public BANCORV3_ETH_ADDRESS =
IERC20TokenV06(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);
IEtherTokenV06 private immutable WETH;
constructor(IEtherTokenV06 weth)
public
{
WETH = weth;
}
function _tradeBancorV3(
IERC20TokenV06 buyToken,
uint256 sellAmount,
bytes memory bridgeData
)
public
internal
returns (uint256 amountOut)
{
IBancorV3 router;
IERC20TokenV06[] memory path;
address[] memory _path;
uint256 payableAmount = 0;
{
(router, _path) = abi.decode(bridgeData, (IBancorV3, address[]));
// To get around `abi.decode()` not supporting interface array types.
@ -72,11 +86,26 @@ contract MixinBancorV3 {
path[path.length - 1] == buyToken,
"MixinBancorV3/LAST_ELEMENT_OF_PATH_MUST_MATCH_OUTPUT_TOKEN"
);
// Grant the BancorV3 router an allowance to sell the first token.
path[0].approveIfBelow(address(router), sellAmount);
//swap WETH->ETH as Bancor only deals in ETH
if(_path[0] == address(WETH)) {
//withdraw the sell amount of WETH for ETH
WETH.withdraw(sellAmount);
payableAmount = sellAmount;
// set _path[0] to the ETH address if WETH is our buy token
_path[0] = address(BANCORV3_ETH_ADDRESS);
} else {
// Grant the BancorV3 router an allowance to sell the first token.
path[0].approveIfBelow(address(router), sellAmount);
}
// if we are buying WETH we need to swap to ETH and deposit into WETH after the swap
if(_path[1] == address(WETH)){
_path[1] = address(BANCORV3_ETH_ADDRESS);
}
uint256 amountOut = router.tradeBySourceAmount(
uint256 amountOut = router.tradeBySourceAmount{value: payableAmount}(
_path[0],
_path[1],
// Sell all tokens we hold.
@ -89,6 +118,11 @@ contract MixinBancorV3 {
address(this)
);
// if we want to return WETH deposit the ETH amount we sold
if(buyToken == WETH){
WETH.deposit{value: amountOut}();
}
return amountOut;
}
}

View File

@ -34,7 +34,8 @@
"contracts:gen": "contracts-gen generate",
"contracts:copy": "contracts-gen copy",
"publish:private": "yarn build && gitpkg publish",
"sampler-size": "jq .compilerOutput.evm.deployedBytecode.object -- test/generated-artifacts/ERC20BridgeSampler.json | echo $(( $(wc -c) / 2 - 1 ))"
"sampler-size": "jq .compilerOutput.evm.deployedBytecode.object -- test/generated-artifacts/ERC20BridgeSampler.json | echo $(( $(wc -c) / 2 - 1 ))",
"list:deps": "yarn lerna list -l"
},
"config": {
"publicInterfaceContracts": "ERC20BridgeSampler,BalanceChecker,FakeTaker",

View File

@ -208,6 +208,8 @@ export function getErc20BridgeSourceToBridgeSource(source: ERC20BridgeSource): s
return encodeBridgeSourceId(BridgeProtocol.Platypus, 'Platypus');
case ERC20BridgeSource.MeshSwap:
return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'MeshSwap');
case ERC20BridgeSource.BancorV3:
return encodeBridgeSourceId(BridgeProtocol.BancorV3, 'BancorV3');
default:
throw new Error(AggregationError.NoBridgeForSource);
}
@ -387,7 +389,7 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
break;
case ERC20BridgeSource.BancorV3:
const bancorV3FillData = (order as OptimizedMarketBridgeOrder<BancorFillData>).fillData;
bridgeData = encoder.encode([bancorV3FillData.networkAddress, bancorFillData.path, bancor]);
bridgeData = encoder.encode([bancorV3FillData.networkAddress, bancorV3FillData.path]);
break;
default:
throw new Error(AggregationError.NoBridgeForSource);

View File

@ -713,6 +713,7 @@ export class SamplerOperations {
public getBancorV3SellQuotes(
networkAddress: string,
networkInfoAddress: string,
path: string[],
takerFillAmounts: BigNumber[],
): SourceQuoteOperation<BancorFillData> {
@ -721,13 +722,14 @@ export class SamplerOperations {
fillData: { networkAddress, path},
contract: this._samplerContract,
function: this._samplerContract.sampleBuysFromBancorV3,
params: [networkAddress, path, takerFillAmounts],
params: [networkInfoAddress, path, takerFillAmounts],
});
}
// Unimplemented
public getBancorV3BuyQuotes(
networkAddress: string,
networkInfoAddress: string,
path: string[],
makerFillAmounts: BigNumber[],
): SourceQuoteOperation<BancorFillData> {
@ -736,7 +738,7 @@ export class SamplerOperations {
fillData: { networkAddress, path},
contract: this._samplerContract,
function: this._samplerContract.sampleBuysFromBancorV3,
params: [networkAddress, path, makerFillAmounts],
params: [networkInfoAddress, path, makerFillAmounts],
});
}
@ -1710,9 +1712,10 @@ export class SamplerOperations {
}
case ERC20BridgeSource.BancorV3: {
return this.getBancorV3SellQuotes(
BANCORV3_NETWORK_BY_CHAIN_ID[this.chainId],
BANCORV3_NETWORK_INFO_BY_CHAIN_ID[this.chainId],
[takerToken,makerToken],
takerFillAmounts
[takerToken, makerToken],
takerFillAmounts,
);
}
default:
@ -2044,10 +2047,11 @@ export class SamplerOperations {
);
}
case ERC20BridgeSource.BancorV3: {
return this.getBancorV3SellQuotes(
return this.getBancorV3BuyQuotes(
BANCORV3_NETWORK_BY_CHAIN_ID[this.chainId],
BANCORV3_NETWORK_INFO_BY_CHAIN_ID[this.chainId],
[takerToken,makerToken],
makerFillAmounts
[takerToken, makerToken],
makerFillAmounts,
);
}
default: