-
-
Save gorgos/2e0b24f59289bd7629797c9cb3a92620 to your computer and use it in GitHub Desktop.
// 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 {} | |
} |
@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.
@gorgos Thanks, great!
putting the balancer addresses in here would have been too practical
putting the balancer addresses in here would have been too practical
Well, the addresses depend on the network and pool you want to use.
How to call it ?
I have deployed it and set the function pay parameter is 10.
BPOOL is Core Pool Factory: 0x8f7F78080219d4066A8036ccD30D588B416a40DB refer to link : https://docs.balancer.finance/smart-contracts/addresses.
kovan weth : 0xd0A1E359811322d97991E03f863a0C30C2cF029C
kovan dai : 0xFf795577d9AC8bD7D90Ee22b6C1703490b6512FD
I make the transaction but fail. tx: https://kovan.etherscan.io/tx/0xba5879f01570b56595ab18f872de84cf97c7761a958c47a864a544ca19c6dcd5
Do I make some parameter mistake?
@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 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.