// SPDX-License-Identifier: MIT | |
pragma solidity 0.7.2; | |
interface PoolInterface { | |
function swapExactAmountIn(address, uint, address, uint, uint) external returns (uint, uint); | |
function swapExactAmountOut(address, uint, address, uint, uint) external returns (uint, uint); | |
} | |
interface TokenInterface { | |
function balanceOf(address) external returns (uint); | |
function allowance(address, address) external returns (uint); | |
function approve(address, uint) external returns (bool); | |
function transfer(address, uint) external returns (bool); | |
function transferFrom(address, address, uint) external returns (bool); | |
function deposit() external payable; | |
function withdraw(uint) external; | |
} | |
contract BalancerTrader { | |
PoolInterface public bPool; | |
TokenInterface public daiToken; | |
TokenInterface public weth; | |
constructor(PoolInterface bPool_, TokenInterface daiToken_, TokenInterface weth_) { | |
bPool = bPool_; | |
daiToken = daiToken_; | |
weth = weth_; | |
} | |
function pay(uint paymentAmountInDai) public payable { | |
if (msg.value > 0) { | |
_swapEthForDai(paymentAmountInDai); | |
} else { | |
require(daiToken.transferFrom(msg.sender, address(this), paymentAmountInDai)); | |
} | |
} | |
function _swapEthForDai(uint daiAmount) private { | |
_wrapEth(); // wrap ETH and approve to balancer pool | |
PoolInterface(bPool).swapExactAmountOut( | |
address(weth), | |
type(uint).max, // maxAmountIn, set to max -> use all sent ETH | |
address(daiToken), | |
daiAmount, | |
type(uint).max // maxPrice, set to max -> accept any swap prices | |
); | |
require(daiToken.transfer(msg.sender, daiToken.balanceOf(address(this))), "ERR_TRANSFER_FAILED"); | |
_refundLeftoverEth(); | |
} | |
function _wrapEth() private { | |
weth.deposit{ value: msg.value }(); | |
if (weth.allowance(address(this), address(bPool)) < msg.value) { | |
weth.approve(address(bPool), type(uint).max); | |
} | |
} | |
function _refundLeftoverEth() private { | |
uint wethBalance = weth.balanceOf(address(this)); | |
if (wethBalance > 0) { | |
// refund leftover ETH | |
weth.withdraw(wethBalance); | |
(bool success,) = msg.sender.call{ value: wethBalance }(""); | |
require(success, "ERR_ETH_FAILED"); | |
} | |
} | |
receive() external payable {} | |
} |
This comment has been minimized.
This comment has been minimized.
@kavofa I had copied the wrong code, fixed now. The code in the blog post was correct by the way. Keep in mind that the blog post is not a full code example. |
This comment has been minimized.
This comment has been minimized.
@gorgos Thanks, great! |
This comment has been minimized.
This comment has been minimized.
putting the balancer addresses in here would have been too practical |
This comment has been minimized.
This comment has been minimized.
Well, the addresses depend on the network and pool you want to use. |
This comment has been minimized.
This comment has been minimized.
How to call it ? |
This comment has been minimized.
This comment has been minimized.
@tigermumu Yes the pool address is incorrect. As mentioned in the blog post, you can find valid pool addresses via https://kovan.pools.balancer.exchange/#//. The factory address you used it for creating new pools. |
This comment has been minimized.
This isn't a working example.
The things I listed below will throw an error on compilation.
PoolInterface
andTokenInterface
are already defiend in the BalancerProxy contract.daiToken
,weth
andbPool
are not difiend.Please fix or remove from your blog post, as the code is stated as working.